#ifdef SYSTEMC /* * $Id: Decod_genMealy.cpp 88 2008-12-10 18:31:39Z rosiere $ * * [ 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_begin(Decod,FUNCTION); log_function(Decod,FUNCTION,_name.c_str()); //----------------------------------- // Initialization //----------------------------------- Tcontrol_t context_event_val = false; 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; predict_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 * select = _priority->select(); 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; Tcontext_t x = it->grp; uint32_t y = it->elt; // 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) { log_printf(TRACE,Decod,FUNCTION," * IFETCH [%d][%d]",x,y); 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])+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+1; _decod_instruction->_is_delay_slot = internal_CONTEXT_IS_DELAY_SLOT [x]; // Test IFetch exception Texception_t ifetch_exception = PORT_READ(in_IFETCH_EXCEPTION [x]); if (ifetch_exception == EXCEPTION_IFETCH_NONE) { // 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 (%.8x)",addr,(addr<<2)); log_printf(TRACE,Decod,FUNCTION," * is_delay_slot : %d",internal_CONTEXT_IS_DELAY_SLOT [x]); instruction_decod (_decod_instruction, _decod_param[x]); } else { // No decod : nop instruction_l_nop (_decod_instruction, _decod_param[x]); _decod_instruction->_exception_use = EXCEPTION_USE_NONE; _decod_instruction->_exception = exception_ifetch_to_exception_decod(ifetch_exception); // INSTRUCTION_TLB // INSTRUCTION_PAGE // BUS_ERROR if (_decod_instruction->_is_delay_slot) _decod_instruction->_address_next = _decod_instruction->_address_previous; else _decod_instruction->_address_next = _decod_instruction->_address; _decod_instruction->_event_type = EVENT_TYPE_EXCEPTION; } Ttype_t type = _decod_instruction->_type; Tdepth_t depth = (_param->_have_port_depth)?PORT_READ(in_CONTEXT_DEPTH [x]):0; // DEPTH_CURRENT 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], depth); PORT_WRITE(out_DECOD_TYPE [i], type); PORT_WRITE(out_DECOD_OPERATION [i], _decod_instruction->_operation ); PORT_WRITE(out_DECOD_NO_EXECUTE [i], _decod_instruction->_no_execute ); 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 ); // PORT_WRITE(out_DECOD_EXCEPTION [i], _decod_instruction->_exception ); if (type == TYPE_BRANCH) { log_printf(TRACE,Decod,FUNCTION," * type is branch"); log_printf(TRACE,Decod,FUNCTION," * address src : %.8x (%.8x)",_decod_instruction->_address ,_decod_instruction->_address <<2); log_printf(TRACE,Decod,FUNCTION," * address dest : %.8x (%.8x)",_decod_instruction->_address_next,_decod_instruction->_address_next<<2); 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_depth) 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, the DS don't execute } 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); if (_param->_have_port_depth) PORT_WRITE(out_CONTEXT_EVENT_DEPTH , depth); 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) { 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. } log_printf(TRACE,Decod,FUNCTION," - num_(decod, context, fetch) : %d %d %d",i, x, y); log_printf(TRACE,Decod,FUNCTION," - ifetch_ack : %d",ifetch_ack [x][y]); log_printf(TRACE,Decod,FUNCTION," - context_event_val : %d",context_event_val ); log_printf(TRACE,Decod,FUNCTION," - predict_val : %d",predict_val [i] ); log_printf(TRACE,Decod,FUNCTION," - decod_val : %d",decod_val [i] ); 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]); #ifdef STATISTICS internal_DECOD_VAL [i] = decod_val [i]; #endif } log_end(Decod,FUNCTION); }; }; // 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