#ifdef VHDL /* * $Id$ * * [ Description ] * */ #include "Behavioural/Generic/Victim/Victim_Pseudo_LRU/include/Victim_Pseudo_LRU.h" namespace morpheo { namespace behavioural { namespace generic { namespace victim { namespace victim_pseudo_lru { void Victim_Pseudo_LRU::vhdl_body (Vhdl * & vhdl) { vhdl->set_body (""); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body ("-- Access"); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body (""); vhdl->set_body ("-- Tree of Pseudo-LRU - example to 8 entity"); vhdl->set_body ("--"); vhdl->set_body ("-- 4-5-6-7? "); vhdl->set_body ("-- 0_______|_______1 "); vhdl->set_body ("-- | | "); vhdl->set_body ("-- 2-3? 6-7? "); vhdl->set_body ("-- 0___|___1 0___|___1 "); vhdl->set_body ("-- | | | | "); vhdl->set_body ("-- 1? 3? 5? 7? "); vhdl->set_body ("-- 0_|_1 0_|_1 0_|_1 0_|_1 "); vhdl->set_body ("-- | | | | | | | | "); vhdl->set_body ("-- Way Way Way Way Way Way Way Way "); vhdl->set_body ("-- 0 1 2 3 4 5 6 7 "); for (uint32_t i=0; i<_param->_nb_access; i++) { vhdl->set_body (""); // Read the table std::string access_address; if (_param->_size_table>1) access_address = "conv_integer(in_ACCESS_"+toString(i)+"_ADDRESS)"; else access_address = "0"; vhdl->set_body ("access_entry_"+toString(i)+" <= reg_TABLE ("+access_address+");"); vhdl->set_body (""); for (int32_t j=static_cast(log2(_param->_nb_entity)-1); j>=0; j--) { vhdl->set_body ("access_entity_"+toString(i)+"("+toString(j)+") <= "); uint32_t cpt=0; for (int32_t k=(1<(_param->_nb_entity-1); k+=(1<<(j+1))) { std::string cond = ""; // Create the condition for (uint32_t l=j+1; l(log2(_param->_nb_entity));l++) { if (l==static_cast(j+1)) cond += "when"; else cond += " and"; cond += " access_entity_"+toString(i)+"("+toString(l)+") = '"+toString((cpt>>(l-(j+1)))&1)+"'"; } std::string print_else = (k==(1<set_body ("\t"+print_else+"access_entry_"+toString(i)+"("+toString(k)+") "+cond); cpt ++; } vhdl->set_body ("\t;"); } } vhdl->set_body (""); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body ("-- Update"); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body (""); vhdl->set_body ("-- port access"); for (uint32_t i=0; i<_param->_nb_access; i++) for (int32_t j=static_cast(log2(_param->_nb_entity)-1); j>=0; j--) { uint32_t cpt=0; for (int32_t k=(1<(_param->_nb_entity-1); k+=(1<<(j+1))) { bool have_cond = false; std::string cond = ""; // condition to change the bit for (uint32_t l=j+1; l(log2(_param->_nb_entity));l++) { have_cond = true; if (l==static_cast(j+1)) cond += "when"; else cond += " and"; cond += " access_entity_"+toString(i)+"("+toString(l)+")='"+toString((cpt>>(l-(j+1)))&1)+"'"; } vhdl->set_body ("access_next_entry_"+toString(i)+"("+toString(k)+") <="); vhdl->set_body ("\tnot access_entity_"+toString(i)+"("+toString(j)+") "+cond); if (have_cond == true) vhdl->set_body ("\telse access_entry_"+toString(i)+"("+toString(k)+")"); vhdl->set_body ("\t;"); cpt ++; } } vhdl->set_body (""); vhdl->set_body ("-- port update"); for (uint32_t i=0; i<_param->_nb_update; i++) for (int32_t j=static_cast(log2(_param->_nb_entity)-1); j>=0; j--) { uint32_t cpt=0; for (int32_t k=(1<(_param->_nb_entity-1); k+=(1<<(j+1))) { bool have_cond = false; std::string cond = ""; // condition to change the bit for (uint32_t l=j+1; l(log2(_param->_nb_entity));l++) { have_cond = true; if (l==static_cast(j+1)) cond += "when"; else cond += " and"; cond += " in_UPDATE_"+toString(i)+"_ENTITY("+toString(l)+")='"+toString((cpt>>(l-(j+1)))&1)+"'"; } vhdl->set_body ("update_next_entry_"+toString(i)+"("+toString(k)+") <="); vhdl->set_body ("\tnot in_UPDATE_"+toString(i)+"_ENTITY("+toString(j)+") "+cond); if (have_cond == true) { std::string update_address; if (_param->_size_table>1) update_address = "conv_integer(in_UPDATE_"+toString(i)+"_ADDRESS)"; else update_address = "0"; vhdl->set_body ("\telse reg_TABLE ("+update_address+")("+toString(k)+")"); } vhdl->set_body ("\t;"); cpt ++; } } vhdl->set_body (""); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body ("-- Transition"); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body (""); vhdl->set_body ("reg_TABLE_write: process (in_CLOCK)"); vhdl->set_body ("begin"); vhdl->set_body ("\tif in_CLOCK'event and in_CLOCK = '1' then"); vhdl->set_body ("\t\t-- Access port"); for (uint32_t i=0; i<_param->_nb_access; i++) { std::string access_address; if (_param->_size_table>1) access_address = "conv_integer(in_ACCESS_"+toString(i)+"_ADDRESS)"; else access_address = "0"; vhdl->set_body ("\t\tif (in_ACCESS_"+toString(i)+"_VAL = '1') then"); vhdl->set_body ("\t\t\treg_TABLE ("+access_address+") <= access_next_entry_"+toString(i)+";"); vhdl->set_body ("\t\tend if;"); } vhdl->set_body ("\t\t-- Update port"); for (uint32_t i=0; i<_param->_nb_update; i++) { std::string update_address; if (_param->_size_table>1) update_address = "conv_integer(in_UPDATE_"+toString(i)+"_ADDRESS)"; else update_address = "0"; vhdl->set_body ("\t\tif (in_UPDATE_"+toString(i)+"_VAL = '1') then"); vhdl->set_body ("\t\t\treg_TABLE ("+update_address+") <= update_next_entry_"+toString(i)+";"); vhdl->set_body ("\t\tend if;"); } vhdl->set_body ("\tend if;"); vhdl->set_body ("end process reg_TABLE_write;"); vhdl->set_body (""); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body ("-- Output"); vhdl->set_body ("-----------------------------------------------------------------------------"); vhdl->set_body (""); vhdl->set_body ("-- Ack is always "); vhdl->set_body (""); for (uint32_t i=0; i<_param->_nb_access; i++) { vhdl->set_body ("out_ACCESS_"+toString(i)+"_ACK <= '1';"); vhdl->set_body ("out_ACCESS_"+toString(i)+"_ENTITY <= access_entity_"+toString(i)+" when in_ACCESS_"+toString(i)+"_VAL = '1' else (others => '0');"); } vhdl->set_body (""); for (uint32_t i=0; i<_param->_nb_update; i++) { vhdl->set_body ("out_UPDATE_"+toString(i)+"_ACK <= '1';"); } }; }; // end namespace victim_pseudo_lru }; // end namespace victim }; // end namespace generic }; // end namespace behavioural }; // end namespace morpheo #endif