#ifdef SYSTEMC /* * $Id$ * * [ Description ] * */ #include "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod/include/Decod.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_front_end { namespace front_end { namespace decod_unit { namespace decod { #undef FUNCTION #define FUNCTION "Decod::genMealy" void Decod::genMealy (void) { log_printf(TRACE,Decod,FUNCTION,"Begin"); //----------------------------------- // Initialization //----------------------------------- Tcontrol_t context_event_val; Tcontrol_t ifetch_ack [_param->_nb_context][_param->_max_nb_inst_fetch]; for (uint32_t i=0; i<_param->_nb_context; i++) for (uint32_t j=0; j<_param->_nb_inst_fetch[i]; j++) ifetch_ack [i][j] = false; Tcontrol_t predict_val [_param->_nb_inst_decod]; Tcontrol_t decod_val [_param->_nb_inst_decod]; for (uint32_t i=0; i<_param->_nb_inst_decod; i++) { decod_val [i] = false; } Tcontrol_t can_continue [_param->_nb_context]; Tcontrol_t can_continue_next [_param->_nb_context]; for (uint32_t i=0; i<_param->_nb_context; i++) { internal_CONTEXT_HAVE_TRANSACTION [i] = false; internal_CONTEXT_ADDRESS_PREVIOUS [i] = reg_CONTEXT_ADDRESS_PREVIOUS [i]; internal_CONTEXT_IS_DELAY_SLOT [i] = reg_CONTEXT_IS_DELAY_SLOT [i]; can_continue [i] = PORT_READ(in_CONTEXT_DECOD_ENABLE [i]); can_continue_next [i] = PORT_READ(in_CONTEXT_DECOD_ENABLE [i]); } //----------------------------------- // Loop of decod //----------------------------------- // scan all decod "slot_out" std::list::iterator it=select.begin(); for (uint32_t i=0; i<_param->_nb_inst_decod; i++) { while ((it != select.end()) and // have a no scanned "slot_in" ? (decod_val [i] == false) and // have not a previous selected entry? (context_event_val == false)) // Have not a context_event (spr_access, exception, ...) { predict_val [i] = false; context_event_val = false; Tcontext_t x = it->_context ; uint32_t y = it->_inst_fetch; // Test if this instruction is valid if ((PORT_READ(in_IFETCH_VAL [x][y]) == 1) and // entry is valid (can_continue [x] == 1)) // context can decod instruction (have not a previous event) { can_continue [x] = can_continue_next [x]; decod_val [i] = true; // fetch_val and decod_enable ifetch_ack [x][y] = PORT_READ(in_DECOD_ACK [i]); // fetch_val and decod_enable and decod_ack Tgeneral_data_t addr = PORT_READ(in_IFETCH_ADDRESS [x])+4*y; _decod_instruction->_instruction = PORT_READ(in_IFETCH_INSTRUCTION [x][y]); _decod_instruction->_context_id = x; _decod_instruction->_address_previous = internal_CONTEXT_ADDRESS_PREVIOUS [x]; _decod_instruction->_address = addr; //Compute the current address _decod_instruction->_address_next = addr+4; _decod_instruction->_is_delay_slot = internal_CONTEXT_IS_DELAY_SLOT [x]; // Decod ! log_printf(TRACE,Decod,FUNCTION,"DECOD [%d]",i); log_printf(TRACE,Decod,FUNCTION," * context : %d",x); log_printf(TRACE,Decod,FUNCTION," * fetch : %d",y); log_printf(TRACE,Decod,FUNCTION," * address : %.8x",addr); log_printf(TRACE,Decod,FUNCTION," * is_delay_slot : %d",internal_CONTEXT_IS_DELAY_SLOT [x]); instruction_decod (_decod_instruction, _decod_param[x]); Ttype_t type = _decod_instruction->_type; if (_param->_have_port_context_id) PORT_WRITE(out_DECOD_CONTEXT_ID [i], x); if (_param->_have_port_depth) PORT_WRITE(out_DECOD_DEPTH [i], PORT_READ(in_CONTEXT_DEPTH [x])); PORT_WRITE(out_DECOD_TYPE [i], type); PORT_WRITE(out_DECOD_OPERATION [i], _decod_instruction->_operation ); PORT_WRITE(out_DECOD_IS_DELAY_SLOT [i], _decod_instruction->_is_delay_slot ); PORT_WRITE(out_DECOD_ADDRESS [i], addr); PORT_WRITE(out_DECOD_HAS_IMMEDIAT [i], _decod_instruction->_has_immediat ); PORT_WRITE(out_DECOD_IMMEDIAT [i], _decod_instruction->_immediat ); PORT_WRITE(out_DECOD_READ_RA [i], _decod_instruction->_read_ra ); PORT_WRITE(out_DECOD_NUM_REG_RA [i], _decod_instruction->_num_reg_ra ); PORT_WRITE(out_DECOD_READ_RB [i], _decod_instruction->_read_rb ); PORT_WRITE(out_DECOD_NUM_REG_RB [i], _decod_instruction->_num_reg_rb ); PORT_WRITE(out_DECOD_READ_RC [i], _decod_instruction->_read_rc ); PORT_WRITE(out_DECOD_NUM_REG_RC [i], _decod_instruction->_num_reg_rc ); PORT_WRITE(out_DECOD_WRITE_RD [i], _decod_instruction->_write_rd ); PORT_WRITE(out_DECOD_NUM_REG_RD [i], _decod_instruction->_num_reg_rd ); PORT_WRITE(out_DECOD_WRITE_RE [i], _decod_instruction->_write_re ); PORT_WRITE(out_DECOD_NUM_REG_RE [i], _decod_instruction->_num_reg_re ); PORT_WRITE(out_DECOD_EXCEPTION_USE [i], _decod_instruction->_exception_use ); if (type == TYPE_BRANCH) { predict_val [i] = ifetch_ack [x][y] // and decod_val [i] ; decod_val [i] &= PORT_READ(in_PREDICT_ACK [i]);// predict_ack and fetch_val and decod_enable ifetch_ack [x][y] &= PORT_READ(in_PREDICT_ACK [i]);// predict_ack and fetch_val and decod_enable and decod_ack if (_param->_have_port_context_id) PORT_WRITE(out_PREDICT_CONTEXT_ID [i],x); PORT_WRITE(out_PREDICT_MATCH_INST_IFETCH_PTR [i],y == ((_param->_have_port_inst_ifetch_ptr)?PORT_READ(in_IFETCH_INST_IFETCH_PTR [x]):0)); PORT_WRITE(out_PREDICT_BRANCH_STATE [i],PORT_READ(in_IFETCH_BRANCH_STATE [x])); if (_param->_have_port_branch_update_prediction_id) PORT_WRITE(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [i],PORT_READ(in_IFETCH_BRANCH_UPDATE_PREDICTION_ID [x])); PORT_WRITE(out_PREDICT_BRANCH_CONDITION [i],_decod_instruction->_branch_condition ); // PORT_WRITE(out_PREDICT_BRANCH_STACK_WRITE [i],_decod_instruction->_branch_stack_write); PORT_WRITE(out_PREDICT_BRANCH_DIRECTION [i],_decod_instruction->_branch_direction ); PORT_WRITE(out_PREDICT_ADDRESS_SRC [i],_decod_instruction->_address ); PORT_WRITE(out_PREDICT_ADDRESS_DEST [i],_decod_instruction->_address_next ); //can_continue_next [x] = PORT_READ(in_PREDICT_CAN_CONTINUE [i]); // can continue is set if direction is "not take" (also, continue is sequential order) can_continue_next [x] = false; // one branch per context } Tevent_type_t event_type = _decod_instruction->_event_type; if (event_type != EVENT_TYPE_NONE) { // speculative jump at the exception handler // if type = TYPE_BRANCH, also event_type == EVENT_TYPE_NONE context_event_val = ifetch_ack [x][y] // and decod_val [i] ; decod_val [i] &= PORT_READ(in_CONTEXT_EVENT_ACK);// context_event_ack and fetch_val and decod_enable ifetch_ack [x][y] &= PORT_READ(in_CONTEXT_EVENT_ACK);// context_event_ack and fetch_val and decod_enable and decod_ack if (_param->_have_port_context_id) PORT_WRITE(out_CONTEXT_EVENT_CONTEXT_ID , x); PORT_WRITE(out_CONTEXT_EVENT_TYPE , _decod_instruction->_event_type ); PORT_WRITE(out_CONTEXT_EVENT_IS_DELAY_SLOT, _decod_instruction->_is_delay_slot ); PORT_WRITE(out_CONTEXT_EVENT_ADDRESS , _decod_instruction->_address ); PORT_WRITE(out_CONTEXT_EVENT_ADDRESS_EPCR , _decod_instruction->_address_next ); } // fetch_ack = // ((event_type == EVENT_TYPE_NONE) or ((event_type != EVENT_TYPE_NONE) and context_event_ack)) and // ((type == TYPE_BRANCH ) or ((type != TYPE_BRANCH ) and predict_ack )) and // fetch_val and decod_ack and decod_enable and true (is decod_val) // To compute the "next previous" address Tcontrol_t have_transaction = ifetch_ack [x][y]; internal_CONTEXT_HAVE_TRANSACTION [x] |= have_transaction; if (have_transaction) { #ifdef STATISTICS (*_stat_sum_inst_decod) ++; #endif internal_CONTEXT_ADDRESS_PREVIOUS [x] = addr; internal_CONTEXT_IS_DELAY_SLOT [x] = (type == TYPE_BRANCH); // next is a delay slot if current have branch type } can_continue [x] &= have_transaction; // to have a in order decod !!! if a previous instruction can decod, also next instruction can't decod. } it ++; } } //----------------------------------- // Write output //----------------------------------- for (uint32_t i=0; i<_param->_nb_context; i++) for (uint32_t j=0; j<_param->_nb_inst_fetch[i]; j++) PORT_WRITE(out_IFETCH_ACK [i][j], ifetch_ack [i][j]); PORT_WRITE(out_CONTEXT_EVENT_VAL, context_event_val); for (uint32_t i=0; i<_param->_nb_inst_decod; i++) { PORT_WRITE(out_PREDICT_VAL [i], predict_val [i]); PORT_WRITE(out_DECOD_VAL [i], decod_val [i]); } log_printf(FUNC,Decod,FUNCTION,"End"); }; }; // end namespace decod }; // end namespace decod_unit }; // end namespace front_end }; // end namespace multi_front_end }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif