#ifdef VHDL /* * $Id: Stat_List_unit_vhdl_body.cpp 135 2009-07-17 08:59:05Z rosiere $ * * [ Description ] * */ #include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Rename_unit/Register_translation_unit/Stat_List_unit/include/Stat_List_unit.h" namespace morpheo { namespace behavioural { namespace core { namespace multi_ooo_engine { namespace ooo_engine { namespace rename_unit { namespace register_translation_unit { namespace stat_list_unit { #undef FUNCTION #define FUNCTION "Stat_List_unit::vhdl_body" void Stat_List_unit::vhdl_body (Vhdl * & vhdl) { log_printf(FUNC,Stat_List_unit,FUNCTION,"Begin"); uint32_t size_bank = log2(_param->_nb_bank); uint32_t size_gpr_ptr = log2(_param->_nb_general_register_by_bank); uint32_t size_spr_ptr = log2(_param->_nb_special_register_by_bank); uint32_t LSB_gpr_num_reg = 0; uint32_t MSB_gpr_num_reg = log2(_param->_nb_general_register_by_bank) - 1; uint32_t LSB_gpr_num_bank = MSB_gpr_num_reg+1; uint32_t MSB_gpr_num_bank = _param->_size_general_register -1 ; uint32_t LSB_spr_num_reg = 0; uint32_t MSB_spr_num_reg = log2(_param->_nb_special_register_by_bank) - 1; uint32_t LSB_spr_num_bank = MSB_spr_num_reg+1; uint32_t MSB_spr_num_bank = _param->_size_special_register -1; vhdl->set_comment(0,"====================================================="); vhdl->set_comment(0,"=====[ CONSTANT ]===================================="); vhdl->set_comment(0,"====================================================="); for (uint32_t j=0; j<_param->_nb_inst_insert; j++) vhdl->set_body (0,"internal_INSERT_"+toString(j)+"_ACK <= '1';"); for (uint32_t j=0; j<_param->_nb_inst_insert; j++) vhdl->set_body (0," out_INSERT_"+toString(j)+"_ACK <= internal_INSERT_"+toString(j)+"_ACK;"); for (uint32_t j=0; j<_param->_nb_inst_retire; j++) vhdl->set_body (0,"internal_RETIRE_"+toString(j)+"_ACK <= '1';"); for (uint32_t j=0; j<_param->_nb_inst_retire; j++) vhdl->set_body (0," out_RETIRE_"+toString(j)+"_ACK <= internal_RETIRE_"+toString(j)+"_ACK;"); vhdl->set_body (0,""); vhdl->set_body (0,"transition: process (in_CLOCK)"); // vhdl->set_body (0,"variable gpr_stat_list_next : Tstat_list_gpr;"); // vhdl->set_body (0,"variable spr_stat_list_next : Tstat_list_spr;"); vhdl->set_body (0,"begin -- process transition"); vhdl->set_body (1,"if in_CLOCK'event and in_CLOCK = '1' then"); vhdl->set_body (2,"if in_NRESET = '0' then"); uint32_t gpr = 0; uint32_t spr = 0; vhdl->set_comment(3,"Init Stat List"); vhdl->set_comment(3,"xxx_stat_list : "); vhdl->set_comment(3," [0] is_free"); vhdl->set_comment(3," [1] is_link"); vhdl->set_body (3,""); vhdl->set_comment(3,"gpr_stat_list"); vhdl->set_body (3,""); for (uint32_t i=0; i<_param->_nb_bank; i++) for (uint32_t j=0; j<_param->_nb_general_register_by_bank; j++) if ((gpr++)<_param->_nb_gpr_use_init) { vhdl->set_body (3,"gpr_stat_list("+toString(i)+")("+toString(j)+")<=\"10\";"); } else { vhdl->set_body (3,"gpr_stat_list("+toString(i)+")("+toString(j)+")<=\"00\";"); } vhdl->set_body (3,""); vhdl->set_comment(3,"spr_stat_list"); vhdl->set_body (3,""); for (uint32_t i=0; i<_param->_nb_bank; i++) for (uint32_t j=0; j<_param->_nb_special_register_by_bank; j++) if ((spr++)<_param->_nb_spr_use_init) { vhdl->set_body (3,"spr_stat_list("+toString(i)+")("+toString(j)+")<=\"10\";"); } else { vhdl->set_body (3,"spr_stat_list("+toString(i)+")("+toString(j)+")<=\"00\";"); } vhdl->set_body (3,""); vhdl->set_comment(3,"Init Pointer"); #ifdef SYSTEMC_VHDL_COMPATIBILITY if (size_gpr_ptr>0) vhdl->set_body (3,"reg_GPR_PTR_FREE <= "+std_logic_cst(size_gpr_ptr,1)+";"); if (size_spr_ptr>0) vhdl->set_body (3,"reg_SPR_PTR_FREE <= "+std_logic_cst(size_spr_ptr,1)+";"); #else if (size_gpr_ptr>0) vhdl->set_body (3,"reg_GPR_PTR_FREE <= "+std_logic_cst(size_gpr_ptr,0)+";"); if (size_spr_ptr>0) vhdl->set_body (3,"reg_SPR_PTR_FREE <= "+std_logic_cst(size_spr_ptr,0)+";"); #endif vhdl->set_body (2,"else"); // in_CLOCK'event and in_CLOCK = '1' // vhdl->set_body (2,"gpr_stat_list_next := gpr_stat_list;"); // vhdl->set_body (2,"spr_stat_list_next := spr_stat_list;"); vhdl->set_comment(3,"====================================================="); vhdl->set_comment(3,"=====[ INSERT ]======================================"); vhdl->set_comment(3,"====================================================="); for (uint32_t i=0; i<_param->_nb_inst_insert; i++) { vhdl->set_body (3,"if ((in_INSERT_"+toString(i)+"_VAL and internal_INSERT_"+toString(i)+"_ACK) = '1') then"); { vhdl->set_body (4,"if (in_INSERT_"+toString(i)+"_WRITE_RD = '1') then"); std::string port = "in_INSERT_"+toString(i)+"_NUM_REG_RD_PHY_NEW"; std::string num_bank = (size_bank >0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_bank,LSB_gpr_num_bank)+")"):"0"; std::string num_reg = (size_gpr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_reg ,LSB_gpr_num_reg )+")"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (5,"gpr_stat_list"+addr+" <= \"10\";"); vhdl->set_body (4,"end if;"); // write_rd } { vhdl->set_body (4,"if (in_INSERT_"+toString(i)+"_WRITE_RE = '1') then"); std::string port = "in_INSERT_"+toString(i)+"_NUM_REG_RE_PHY_NEW"; std::string num_bank = (size_bank >0)?("conv_integer("+port+std_logic_range(MSB_spr_num_bank,LSB_spr_num_bank)+")"):"0"; std::string num_reg = (size_spr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_spr_num_reg ,LSB_spr_num_reg )+")"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (5,"spr_stat_list"+addr+" <= \"10\";"); vhdl->set_body (4,"end if;"); // write_re } vhdl->set_body (3,"end if;"); // transaction insert } vhdl->set_comment(3,"====================================================="); vhdl->set_comment(3,"=====[ RETIRE ]======================================"); vhdl->set_comment(3,"====================================================="); for (uint32_t i=0; i<_param->_nb_inst_retire; i++) { vhdl->set_body (3,"if ((in_RETIRE_"+toString(i)+"_VAL and internal_RETIRE_"+toString(i)+"_ACK) = '1') then"); std::string restore = "in_RETIRE_"+toString(i)+"_RESTORE"; // write rd vhdl->set_body (4,"if (in_RETIRE_"+toString(i)+"_WRITE_RD = '1') then"); { std::string restore_old = "in_RETIRE_"+toString(i)+"_RESTORE_RD_PHY_OLD"; { std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RD_PHY_OLD"; std::string num_bank = (size_bank >0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_bank,LSB_gpr_num_bank)+")"):"0"; std::string num_reg = (size_gpr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_reg ,LSB_gpr_num_reg )+")"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (5,"gpr_stat_list"+addr+"(1) <= "+restore+" and "+restore_old+";"); } { std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RD_PHY_NEW"; std::string num_bank = (size_bank >0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_bank,LSB_gpr_num_bank)+")"):"0"; std::string num_reg = (size_gpr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_gpr_num_reg ,LSB_gpr_num_reg )+")"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (5,"if ("+restore+" = '1') then"); vhdl->set_body (5,"gpr_stat_list"+addr+"(1) <= '0';"); vhdl->set_body (5,"end if;"); // write_rd } } vhdl->set_body (4,"end if;"); // write_rd // write re vhdl->set_body (4,"if (in_RETIRE_"+toString(i)+"_WRITE_RE = '1') then"); { std::string restore_old = "in_RETIRE_"+toString(i)+"_RESTORE_RE_PHY_OLD"; { std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RE_PHY_OLD"; std::string num_bank = (size_bank >0)?("conv_integer("+port+std_logic_range(MSB_spr_num_bank,LSB_spr_num_bank)+")"):"0"; std::string num_reg = (size_spr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_spr_num_reg ,LSB_spr_num_reg )+")"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (5,"spr_stat_list"+addr+"(1) <= "+restore+" and "+restore_old+";"); } { std::string port = "in_RETIRE_"+toString(i)+"_NUM_REG_RE_PHY_NEW"; std::string num_bank = (size_bank >0)?("conv_integer("+port+std_logic_range(MSB_spr_num_bank,LSB_spr_num_bank)+")"):"0"; std::string num_reg = (size_spr_ptr>0)?("conv_integer("+port+std_logic_range(MSB_spr_num_reg ,LSB_spr_num_reg )+")"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (5,"if ("+restore+" = '1') then"); vhdl->set_body (5,"spr_stat_list"+addr+"(1) <= '0';"); vhdl->set_body (5,"end if;"); // write_re } } vhdl->set_body (4,"end if;"); // write_re vhdl->set_body (3,"end if;"); // transaction retire } for (uint32_t i=0; i<_param->_nb_reg_free; i++) { { vhdl->set_comment(3,"====================================================="); vhdl->set_comment(3,"=====[ PUSH_GPR ]===================================="); vhdl->set_comment(3,"====================================================="); vhdl->set_body (3,"if ((internal_PUSH_GPR_"+toString(i)+"_VAL and in_PUSH_GPR_"+toString(i)+"_ACK) = '1') then"); std::string num_bank = (size_bank >0)?("conv_integer(internal_PUSH_GPR_"+toString(i)+"_NUM_BANK)"):"0"; std::string num_reg = (size_gpr_ptr>0)?("conv_integer(internal_PUSH_GPR_"+toString(i)+"_NUM_REG )"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (4,"gpr_stat_list"+addr+"(0) <= '1';"); vhdl->set_body (3,"end if;"); } { vhdl->set_comment(3,"====================================================="); vhdl->set_comment(3,"=====[ PUSH_SPR ]===================================="); vhdl->set_comment(3,"====================================================="); vhdl->set_body (3,"if ((internal_PUSH_SPR_"+toString(i)+"_VAL and in_PUSH_SPR_"+toString(i)+"_ACK) = '1') then"); std::string num_bank = (size_bank >0)?("conv_integer(internal_PUSH_SPR_"+toString(i)+"_NUM_BANK)"):"0"; std::string num_reg = (size_spr_ptr>0)?("conv_integer(internal_PUSH_SPR_"+toString(i)+"_NUM_REG )"):"0"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (4,"spr_stat_list"+addr+"(0) <= '1';"); vhdl->set_body (3,"end if;"); } } vhdl->set_comment(3,"====================================================="); vhdl->set_comment(3,"=====[ POINTER ]====================================="); vhdl->set_comment(3,"====================================================="); if (size_gpr_ptr>0) { if (is_power2(_param->_nb_general_register_by_bank)) { if (size_gpr_ptr == 1) vhdl->set_body (3,"reg_GPR_PTR_FREE <= not reg_GPR_PTR_FREE;"); else vhdl->set_body (3,"reg_GPR_PTR_FREE <= reg_GPR_PTR_FREE - "+std_logic_cst(size_gpr_ptr,1)+";"); } else { throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of GPR must a power of 2.")); } } if (size_spr_ptr>0) { if (is_power2(_param->_nb_special_register_by_bank)) { if (size_spr_ptr == 1) vhdl->set_body (3,"reg_SPR_PTR_FREE <= not reg_SPR_PTR_FREE;"); else vhdl->set_body (3,"reg_SPR_PTR_FREE <= reg_SPR_PTR_FREE - "+std_logic_cst(size_spr_ptr,1)+";"); } else { throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of SPR must a power of 2.")); } } vhdl->set_body (2,"end if;"); // in_CLOCK'event and in_CLOCK = '1' vhdl->set_body (1,"end if;"); // if in_NRESET = '0' vhdl->set_body (0,"end process transition;"); { vhdl->set_body (0,""); vhdl->set_comment(0,"====================================================="); vhdl->set_comment(0,"=====[ PUSH_GPR ]===================================="); vhdl->set_comment(0,"====================================================="); vhdl->set_body (0,""); for (uint32_t i=0; i<_param->_nb_reg_free; i++) { uint32_t offset = i*_param->_nb_bank_by_port_free; std::string address; if (size_gpr_ptr > 0) { address = "internal_PUSH_GPR_"+toString(i)+"_NUM_REG"; vhdl->set_body (0,"internal_PUSH_GPR_"+toString(i)+"_NUM_REG <= reg_GPR_PTR_FREE;"); } else { address = "0"; } vhdl->set_body (0,"internal_PUSH_GPR_"+toString(i)+"_VAL <= '1' when"); vhdl->set_body (1,"false"); for (uint32_t j=0; j<_param->_nb_bank_by_port_free; j++) { std::string num_bank = toString(offset+j); std::string num_reg = "conv_integer("+address+")"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (1,"or (gpr_stat_list"+addr+" = \"00\")"); } vhdl->set_body (1,"else '0';"); if (size_bank > 0) { vhdl->set_body (0,"internal_PUSH_GPR_"+toString(i)+"_NUM_BANK <= "); for (uint32_t j=0; j<_param->_nb_bank_by_port_free-1; j++) { uint32_t _num_bank = offset+j; std::string num_bank = toString(_num_bank); std::string num_reg = "conv_integer("+address+")"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (1,std_logic_cst(size_bank,_num_bank)+" when (gpr_stat_list"+addr+" = \"00\") else"); } vhdl->set_body (1,std_logic_cst(size_bank,offset+_param->_nb_bank_by_port_free-1)+";"); } vhdl->set_body (0,"out_PUSH_GPR_"+toString(i)+"_VAL <= internal_PUSH_GPR_"+toString(i)+"_VAL;"); if (is_power2(_param->_nb_general_register_by_bank)) { std::string num_bank = (size_bank > 0)?("internal_PUSH_GPR_"+toString(i)+"_NUM_BANK"):""; std::string num_reg = (size_gpr_ptr > 0)?address:""; std::string conc = ((size_gpr_ptr*size_bank) > 0)?" & ":""; vhdl->set_body (0,"out_PUSH_GPR_"+toString(i)+"_NUM_REG <= "+num_bank+conc+num_reg+";"); } else { throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of GPR must a power of 2.")); } } } { vhdl->set_body (0,""); vhdl->set_comment(0,"====================================================="); vhdl->set_comment(0,"=====[ PUSH_SPR ]===================================="); vhdl->set_comment(0,"====================================================="); vhdl->set_body (0,""); for (uint32_t i=0; i<_param->_nb_reg_free; i++) { uint32_t offset = i*_param->_nb_bank_by_port_free; std::string address; if (size_spr_ptr > 0) { address = "internal_PUSH_SPR_"+toString(i)+"_NUM_REG"; vhdl->set_body (0,"internal_PUSH_SPR_"+toString(i)+"_NUM_REG <= reg_SPR_PTR_FREE;"); } else { address = "0"; } vhdl->set_body (0,"internal_PUSH_SPR_"+toString(i)+"_VAL <= '1' when"); vhdl->set_body (1,"false"); for (uint32_t j=0; j<_param->_nb_bank_by_port_free; j++) { std::string num_bank = toString(offset+j); std::string num_reg = "conv_integer("+address+")"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (1,"or (spr_stat_list"+addr+" = \"00\")"); } vhdl->set_body (1,"else '0';"); if (size_bank > 0) { vhdl->set_body (0,"internal_PUSH_SPR_"+toString(i)+"_NUM_BANK <= "); for (uint32_t j=0; j<_param->_nb_bank_by_port_free-1; j++) { uint32_t _num_bank = offset+j; std::string num_bank = toString(_num_bank); std::string num_reg = "conv_integer("+address+")"; std::string addr = "("+num_bank+")("+num_reg+")"; vhdl->set_body (1,std_logic_cst(size_bank,_num_bank)+" when (spr_stat_list"+addr+" = \"00\") else"); } vhdl->set_body (1,std_logic_cst(size_bank,offset+_param->_nb_bank_by_port_free-1)+";"); } vhdl->set_body (0,"out_PUSH_SPR_"+toString(i)+"_VAL <= internal_PUSH_SPR_"+toString(i)+"_VAL;"); if (is_power2(_param->_nb_special_register_by_bank)) { std::string num_bank = (size_bank > 0)?("internal_PUSH_SPR_"+toString(i)+"_NUM_BANK"):""; std::string num_reg = (size_spr_ptr > 0)?address:""; std::string conc = ((size_spr_ptr*size_bank) > 0)?" & ":""; vhdl->set_body (0,"out_PUSH_SPR_"+toString(i)+"_NUM_REG <= "+num_bank+conc+num_reg+";"); } else { throw ERRORMORPHEO(FUNCTION,_(" No Yet Supported : the Number of SPR must a power of 2.")); } } } log_printf(FUNC,Stat_List_unit,FUNCTION,"End"); }; }; // end namespace stat_list_unit }; // end namespace register_translation_unit }; // end namespace rename_unit }; // end namespace ooo_engine }; // end namespace multi_ooo_engine }; // end namespace core }; // end namespace behavioural }; // end namespace morpheo #endif