#ifdef VHDL /* * $Id: Ifetch_queue_vhdl_body.cpp 137 2010-02-16 12:35:48Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Ifetch_queue/include/Ifetch_queue.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_front_end { namespace front_end { namespace ifetch_unit { namespace ifetch_queue { #undef FUNCTION #define FUNCTION "Ifetch_queue::vhdl_body" void Ifetch_queue::vhdl_body (Vhdl * & vhdl) { log_printf(FUNC,Ifetch_queue,FUNCTION,"Begin"); vhdl->set_comment(0,"========================================="); vhdl->set_comment(0,"===== CONSTANT =========================="); vhdl->set_comment(0,"========================================="); vhdl->set_body (0,""); vhdl->set_body (0,"internal_ICACHE_RSP_ACK <= '1';"); vhdl->set_body (0,"internal_EVENT_RESET_ACK <= '1';"); vhdl->set_body (0,"out_EVENT_RESET_ACK <= '1';"); vhdl->set_body (0,"out_ICACHE_RSP_ACK <= '1';"); vhdl->set_body (0,""); vhdl->set_comment(0,"---------------------------------------------------------------------------"); vhdl->set_comment(0,"TRANSLATION "); vhdl->set_comment(0,"---------------------------------------------------------------------------"); vhdl->set_body (0,"TRANSITION : process (in_CLOCK)"); vhdl->set_body (0,"variable have_instruction_decod : std_logic;"); vhdl->set_body (0,"variable have_instruction_enable : std_logic;"); // vhdl->set_body (0,"variable reg_INSTRUCTION_ENABLE_VAR : std_logic;"); if (_param->_size_queue>1) { vhdl->set_body (0,"variable var_PTR_READ :"+ std_logic(log2(_param->_size_queue))+";"); vhdl->set_body (0,"variable var_PTR_WRITE :"+ std_logic(log2(_param->_size_queue))+";"); } // vhdl->set_body (0,"variable var_EMPTY : std_logic;"); vhdl->set_body (0,"variable var_STATE : Tstate;"); vhdl->set_body (0,"variable var_INSTRUCTION_ENABLE : Tenable;"); vhdl->set_body (0,"variable var_ADDRESS : Tadress;"); if(_param->_have_port_inst_ifetch_ptr) vhdl->set_body (0,"variable var_INST_IFETCH_PTR : Tinst_ptr;"); vhdl->set_body (0,"variable var_BRANCH_STATE : Tbranch_state;"); if(_param->_have_port_depth) vhdl->set_body (0,"variable var_BRANCH_UPDATE_PREDICTION_ID : "+std_logic(_param->_size_depth)+";"); // vhdl->set_body (0,"variable var_internal_ICACHE_RSP_ACK : std_logic;"); if (_param->_have_port_ifetch_queue_ptr) vhdl->set_body (0,"variable var_internal_ICACHE_RSP_PACKET_ID : "+std_logic(_param->_size_ifetch_queue_ptr)+";"); vhdl->set_body (0,"variable var_EXCEPTION : Texception;"); vhdl->set_body (0,"begin -- TRANSITION"); vhdl->set_body (1,"if (in_CLOCK'event and in_CLOCK = '1')then"); vhdl->set_body (0,""); vhdl->set_comment(2,"---------------------------------------------------------------------------"); vhdl->set_comment(2,"Reset"); vhdl->set_comment(2,"---------------------------------------------------------------------------"); vhdl->set_body (2,"if (in_NRESET = '0') then"); if (_param->_size_queue>1) { vhdl->set_body (3,"reg_PTR_READ <= "+std_logic_cst( log2(_param->_size_queue), 0)+";"); vhdl->set_body (3,"reg_PTR_WRITE <= "+std_logic_cst( log2(_param->_size_queue), 0)+";"); } // vhdl->set_body (3,"var_EMPTY := '1';"); for (uint32_t i=0; i<_param->_size_queue; i++) { vhdl->set_body (3,"reg_STATE("+toString(i)+") <= IFETCH_QUEUE_STATE_EMPTY;"); } vhdl->set_body (3,""); vhdl->set_body (2,"else"); vhdl->set_body (3,""); // std::string write = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_WRITE)"; // vhdl->set_body (3,"var_STATE := reg_STATE ("+write+");"); vhdl->set_body (3,"var_STATE := reg_STATE ;"); if (_param->_size_queue>1) { vhdl->set_body (3,"var_PTR_READ := reg_PTR_READ;"); vhdl->set_body (3,"var_PTR_WRITE := reg_PTR_WRITE;"); } // if (_param->_size_queue>1) // { // vhdl->set_body (3,"var_EMPTY := reg_EMPTY ;"); // } vhdl->set_body (3,"var_INSTRUCTION_ENABLE := reg_INSTRUCTION_ENABLE ;"); vhdl->set_body (3,"var_ADDRESS := reg_ADDRESS ;"); if(_param->_have_port_inst_ifetch_ptr) vhdl->set_body (3,"var_INST_IFETCH_PTR := reg_INST_IFETCH_PTR ;"); if (_param->_have_port_ifetch_queue_ptr) // vhdl->set_body (3,"var_BRANCH_UPDATE_PREDICTION_ID := reg_BRANCH_UPDATE_PREDICTION_ID;"); vhdl->set_body (3,"var_BRANCH_STATE := reg_BRANCH_STATE ;"); vhdl->set_body (3,"var_EXCEPTION := reg_EXCEPTION ;"); vhdl->set_comment(3,"---------------------------------------------------------------------------"); vhdl->set_comment(3,"ADDRESS "); vhdl->set_comment(3,"---------------------------------------------------------------------------"); { std::string reg_ptr_write = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_WRITE)"; vhdl->set_body (3,"if ((in_ADDRESS_VAL and internal_ADDRESS_ACK) = '1') then"); vhdl->set_body (3,"var_STATE ("+reg_ptr_write+") := IFETCH_QUEUE_STATE_WAIT_RSP;"); for (uint32_t i=0; i<_param->_nb_instruction; i++) vhdl->set_body (3,"var_INSTRUCTION_ENABLE ("+reg_ptr_write+")("+toString(i)+") := in_address_"+toString(i)+"_instruction_enable;"); vhdl->set_body (3,"var_ADDRESS("+reg_ptr_write+") := in_ADDRESS_INSTRUCTION_ADDRESS;"); if(_param->_have_port_inst_ifetch_ptr) { vhdl->set_body (3,"var_INST_IFETCH_PTR("+reg_ptr_write+") := in_ADDRESS_INST_IFETCH_PTR;"); } vhdl->set_body (3,"var_BRANCH_STATE("+reg_ptr_write+") := in_ADDRESS_BRANCH_STATE;"); if(_param->_have_port_depth) vhdl->set_body (3,"var_BRANCH_UPDATE_PREDICTION_ID := in_ADDRESS_BRANCH_UPDATE_PREDICTION_ID;"); if (_param->_size_queue>1) { vhdl->set_body (3,"if (var_PTR_WRITE ="+std_logic_cst( log2(_param->_size_queue),_param->_size_queue-1)+") then"); vhdl->set_body (3,"var_PTR_WRITE := "+std_logic_cst( log2(_param->_size_queue), 0)+";"); vhdl->set_body (3,"else"); if (_param->_size_ifetch_queue_ptr == 1) vhdl->set_body (3,"var_PTR_WRITE := not var_PTR_WRITE;"); else vhdl->set_body (3,"var_PTR_WRITE := (var_PTR_WRITE +"+std_logic_cst( log2(_param->_size_queue),1)+");"); vhdl->set_body (3,"end if;"); } vhdl->set_body (3,"end if;"); } vhdl->set_comment(3,"---------------------------------------------------------------------------"); vhdl->set_comment(3,"DECOD "); vhdl->set_comment(3,"---------------------------------------------------------------------------"); // have_instruction_decod <= ((internal_DECOD_0_VAL and in_DECOD_0_ACK) or // (internal_DECOD_1_VAL and in_DECOD_1_ACK) or // (internal_DECOD_2_VAL and in_DECOD_2_ACK) or // (internal_DECOD_3_VAL and in_DECOD_3_ACK)); vhdl->set_body (3,"have_instruction_decod := '0';"); vhdl->set_body (3,"have_instruction_enable := '0';"); std::string reg_ptr_read = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_READ)"; for (uint32_t i=0; i<_param->_nb_instruction; i++) { vhdl->set_body (3,"if ((internal_DECOD_"+toString(i)+"_VAL and in_DECOD_"+toString(i)+"_ACK) = '1') then"); vhdl->set_body (4,"have_instruction_decod := '1';"); vhdl->set_body (4,"var_INSTRUCTION_ENABLE ("+reg_ptr_read+")("+toString(i)+") := '0';"); vhdl->set_body (3,"end if;"); vhdl->set_body (4,"have_instruction_enable := have_instruction_enable or var_INSTRUCTION_ENABLE ("+reg_ptr_read+")("+toString(i)+");"); } vhdl->set_body (3,"if (have_instruction_decod = '1') then"); vhdl->set_body (3,"if (have_instruction_enable = '0') then"); vhdl->set_body (4,"var_STATE ("+reg_ptr_read+") := IFETCH_QUEUE_STATE_EMPTY;"); if(_param->_size_queue>1) { vhdl->set_body (4,"if (var_PTR_READ ="+std_logic_cst( log2(_param->_size_queue),_param->_size_queue-1)+") then"); vhdl->set_body (4,"var_PTR_READ := "+std_logic_cst( log2(_param->_size_queue), 0)+"; else"); if (_param->_size_ifetch_queue_ptr == 1) vhdl->set_body (4,"var_PTR_READ := not var_PTR_READ;"); else vhdl->set_body (4,"var_PTR_READ := var_PTR_READ +"+std_logic_cst( log2(_param->_size_queue),1)+";"); vhdl->set_body (4,"end if;"); } vhdl->set_body (3,"end if;"); vhdl->set_body (3,"end if;"); vhdl->set_comment(3,"---------------------------------------------------------------------------"); vhdl->set_comment(3,"ICACHE_RSP "); vhdl->set_comment(3,"---------------------------------------------------------------------------"); { std::string address; if (_param->_have_port_ifetch_queue_ptr) { address="conv_integer(var_internal_ICACHE_RSP_PACKET_ID)"; } else { address="0"; } vhdl->set_body (3,"if ((in_ICACHE_RSP_VAL and internal_ICACHE_RSP_ACK)= '1') then"); if (_param->_have_port_ifetch_queue_ptr) { vhdl->set_body(4,"var_internal_ICACHE_RSP_PACKET_ID := in_ICACHE_RSP_PACKET_ID;"); } for (uint32_t i=0; i<_param->_nb_instruction; i++) vhdl->set_body(3,"reg_DATA("+address+")("+toString(i)+") <= in_ICACHE_RSP_"+toString(i)+"_INSTRUCTION ;"); vhdl->set_body(4,"if (in_ICACHE_RSP_ERROR = ICACHE_ERROR_NONE) then"); vhdl->set_body(5,"var_EXCEPTION("+address+") := EXCEPTION_IFETCH_NONE;"); vhdl->set_body(4,"else if (in_ICACHE_RSP_ERROR = ICACHE_ERROR_BUS_ERROR) then"); vhdl->set_body(5,"var_EXCEPTION("+address+") := EXCEPTION_IFETCH_BUS_ERROR;"); vhdl->set_body (4,"end if;"); vhdl->set_body (4,"end if;"); vhdl->set_body(4,"if (var_STATE("+address+") = IFETCH_QUEUE_STATE_WAIT_RSP) then"); vhdl->set_body(5," var_STATE("+address+") := IFETCH_QUEUE_STATE_HAVE_RSP;"); vhdl->set_body(4,"else if var_STATE("+address+") = IFETCH_QUEUE_STATE_ERROR_WAIT_RSP then"); vhdl->set_body(5," var_STATE("+address+") := IFETCH_QUEUE_STATE_EMPTY;"); vhdl->set_body (4,"end if;"); vhdl->set_body (4,"end if;"); vhdl->set_body (3,"end if;"); } vhdl->set_comment(3,"---------------------------------------------------------------------------"); vhdl->set_comment(3,"EVENT_RESET"); vhdl->set_comment(3,"---------------------------------------------------------------------------"); vhdl->set_body (3,"if ((in_EVENT_RESET_VAL and internal_EVENT_RESET_ACK) = '1' ) then"); for (uint32_t i=0; i<_param->_size_queue; i++) { vhdl->set_body(4,"if (var_STATE("+toString(i)+") = IFETCH_QUEUE_STATE_ERROR_WAIT_RSP) then "); vhdl->set_body(4,"var_STATE("+toString(i)+") := IFETCH_QUEUE_STATE_ERROR_WAIT_RSP;"); vhdl->set_body(4,"else if var_STATE("+toString(i)+") = IFETCH_QUEUE_STATE_WAIT_RSP then "); vhdl->set_body(4,"var_STATE("+toString(i)+") := IFETCH_QUEUE_STATE_ERROR_WAIT_RSP;"); vhdl->set_body(4,"else var_STATE("+toString(i)+") := IFETCH_QUEUE_STATE_EMPTY;"); if (_param->_size_queue>1) vhdl->set_body(5,"var_PTR_READ := var_PTR_WRITE;"); // else // vhdl->set_body(5,"reg_EMPTY <= '1';"); vhdl->set_body(4,"end if;"); vhdl->set_body(4,"end if;"); } //vhdl->set_body (3,"end if;"); vhdl->set_body (3,"end if;"); vhdl->set_comment(3,"---------------------------------------------------------------------------"); vhdl->set_comment(3,"WRITE Register"); vhdl->set_comment(3,"---------------------------------------------------------------------------"); { if (_param->_size_queue>1) { vhdl->set_body (3,"reg_PTR_READ <= var_PTR_READ;"); vhdl->set_body (3,"reg_PTR_WRITE <= var_PTR_WRITE;"); } // vhdl->set_body (3,"reg_EMPTY <= var_EMPTY;"); std::string reg_ptr_write = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_WRITE)"; // vhdl->set_body (3,"reg_STATE ("+reg_ptr_write+") <= var_STATE;"); vhdl->set_body (3,"reg_STATE <= var_STATE;"); for (uint32_t i=0; i<_param->_nb_instruction; i++) vhdl->set_body (3,"reg_INSTRUCTION_ENABLE("+reg_ptr_write+")("+toString(i)+") <= var_INSTRUCTION_ENABLE("+reg_ptr_write+")("+toString(i)+");"); // vhdl->set_body (3,"reg_ADDRESS ("+reg_ptr_write+") <= var_ADDRESS;"); vhdl->set_body (3,"reg_ADDRESS <= var_ADDRESS;"); if(_param->_have_port_inst_ifetch_ptr) //vhdl->set_body (3,"reg_INST_IFETCH_PTR ("+reg_ptr_write+") <= var_INST_IFETCH_PTR;"); vhdl->set_body (3,"reg_INST_IFETCH_PTR <= var_INST_IFETCH_PTR;"); // vhdl->set_body (3,"reg_BRANCH_STATE ("+reg_ptr_write+") <= var_BRANCH_STATE;"); vhdl->set_body (3,"reg_BRANCH_STATE <= var_BRANCH_STATE;"); if(_param->_have_port_depth) vhdl->set_body (3,"reg_BRANCH_UPDATE_PREDICTION_ID("+reg_ptr_write+") <= var_BRANCH_UPDATE_PREDICTION_ID;"); if (_param->_size_queue>1) vhdl->set_body (3,"reg_PTR_WRITE <= var_PTR_WRITE;"); std::string reg_ptr_read = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_READ)"; for (uint32_t i=0; i<_param->_nb_instruction; i++) vhdl->set_body (3,"reg_INSTRUCTION_ENABLE("+reg_ptr_read+") ("+toString(i)+") <= var_INSTRUCTION_ENABLE("+reg_ptr_read+")("+toString(i)+");"); // vhdl->set_body (3,"reg_STATE("+reg_ptr_read+") <= var_STATE;"); if(_param->_size_queue>1) vhdl->set_body (3,"reg_PTR_READ <= var_PTR_READ ;"); // vhdl->set_body (3,"internal_ICACHE_RSP_ACK <= internal_ICACHE_RSP_ACK;"); if (_param->_have_port_ifetch_queue_ptr) { vhdl->set_body (3,"internal_ICACHE_RSP_PACKET_ID <= var_internal_ICACHE_RSP_PACKET_ID;"); std::string address; if (_param->_have_port_ifetch_queue_ptr) address="conv_integer(var_internal_ICACHE_RSP_PACKET_ID)"; else address="0"; // vhdl->set_body (3,"reg_EXCEPTION("+address+") <= var_EXCEPTION;"); vhdl->set_body (3,"reg_EXCEPTION <= var_EXCEPTION;"); } } vhdl->set_body (2,"end if;"); vhdl->set_body (1,"end if;"); vhdl->set_body (0,"end process; -- TRANSITION"); vhdl->set_comment(0,"---------------------------------------------------------------------------"); vhdl->set_comment(0,"GENMOORE"); vhdl->set_comment(0,"---------------------------------------------------------------------------"); vhdl->set_comment(0,"---------------------------------------------------------------------------"); vhdl->set_comment(0,"ADDRESS "); vhdl->set_comment(0,"---------------------------------------------------------------------------"); { std::string reg_ptr_write = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_WRITE)"; vhdl->set_body (1,"internal_ADDRESS_ACK <= '1' WHEN (reg_STATE("+reg_ptr_write+") = IFETCH_QUEUE_STATE_EMPTY) ELSE"); vhdl->set_body (1,"'0';"); vhdl->set_body (1,"out_ADDRESS_ACK <= internal_ADDRESS_ACK;"); if (_param->_have_port_ifetch_queue_ptr) { uint32_t diff_size = _param->_size_ifetch_queue_ptr - log2(_param->_size_queue); std::string complete_size = ""; if (diff_size > 0) complete_size = std_logic_cst(diff_size,0)+" &"; vhdl->set_body (1,"out_ADDRESS_IFETCH_QUEUE_ID <= "+complete_size+" reg_PTR_WRITE;"); } } vhdl->set_comment(0,"---------------------------------------------------------------------------"); vhdl->set_comment(0,"DECOD "); vhdl->set_comment(0,"---------------------------------------------------------------------------"); { std::string reg_ptr_read = (_param->_size_queue==1)?"0":"conv_integer(reg_PTR_READ)"; vhdl->set_body (0,"internal_ack <= '1' WHEN (reg_STATE("+reg_ptr_read+") = IFETCH_QUEUE_STATE_HAVE_RSP) ELSE"); vhdl->set_body (0,"'0';"); for (uint32_t j=0; j<_param->_nb_instruction; j++) { vhdl->set_body(0,"internal_DECOD_"+toString(j)+"_VAL <= (internal_ack AND reg_INSTRUCTION_ENABLE("+reg_ptr_read+")("+toString(j)+"));"); vhdl->set_body(0,"out_DECOD_"+toString(j)+"_VAL <= internal_DECOD_"+toString(j)+"_VAL;"); vhdl->set_body(0,"out_DECOD_"+toString(j)+"_INSTRUCTION <= reg_DATA("+reg_ptr_read+")("+toString(j)+") ;"); vhdl->set_body(0,"out_DECOD_"+toString(j)+"_ADDRESS <= reg_ADDRESS("+reg_ptr_read+")+"+std_logic_cst(_param->_size_instruction,j)+";"); if (_param->_have_port_inst_ifetch_ptr) vhdl->set_body(0,"out_DECOD_"+toString(j)+"_BRANCH_STATE <= reg_BRANCH_STATE("+reg_ptr_read+") when reg_INST_IFETCH_PTR("+reg_ptr_read+") = "+std_logic_cst(_param->_size_inst_ifetch_ptr,j)+" else "+std_logic_cst(_param->_size_branch_state,BRANCH_STATE_NONE)+";"); else vhdl->set_body(0,"out_DECOD_"+toString(j)+"_BRANCH_STATE <= reg_BRANCH_STATE("+reg_ptr_read+");"); if (_param->_have_port_depth) vhdl->set_body(0,"out_DECOD_"+toString(j)+"_BRANCH_UPDATE_PREDICTION_ID <= reg_BRANCH_UPDATE_PREDICTION_ID("+reg_ptr_read+");"); vhdl->set_body(0,"out_DECOD_"+toString(j)+"_EXCEPTION <= reg_EXCEPTION("+reg_ptr_read+");"); } } vhdl->set_body(0,""); log_printf(FUNC,Ifetch_queue,FUNCTION,"End"); }; }; // end namespace ifetch_queue }; // end namespace ifetch_unit }; // end namespace front_end }; // end namespace multi_front_end }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif