#ifdef VHDL /* * $Id$ * * [ Description ] * */ #include "Behavioural/Generic/Victim/Pseudo_LRU/include/Pseudo_LRU.h" namespace morpheo { namespace behavioural { namespace generic { namespace victim { namespace pseudo_lru { void 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 string access_address; if (_param._size_table>1) access_address = "conv_integer(in_ACCESS_ADDRESS_"+toString(i)+")"; 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))) { 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)+"'"; } string print_else = (k==(1<(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; 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; 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_ENTITY_"+toString(i)+"("+toString(l)+")='"+toString((cpt>>(l-(j+1)))&1)+"'"; } vhdl.set_body ("update_next_entry_"+toString(i)+"("+toString(k)+") <="); vhdl.set_body ("\tnot in_UPDATE_ENTITY_"+toString(i)+"("+toString(j)+") "+cond); if (have_cond == true) { string update_address; if (_param._size_table>1) update_address = "conv_integer(in_UPDATE_ADDRESS_"+toString(i)+")"; 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++) { string access_address; if (_param._size_table>1) access_address = "conv_integer(in_ACCESS_ADDRESS_"+toString(i)+")"; else access_address = "0"; vhdl.set_body ("\t\tif (in_ACCESS_VAL_"+toString(i)+" = '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++) { string update_address; if (_param._size_table>1) update_address = "conv_integer(in_UPDATE_ADDRESS_"+toString(i)+")"; else update_address = "0"; vhdl.set_body ("\t\tif (in_UPDATE_VAL_"+toString(i)+" = '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_ACK_"+toString(i)+" <= '1';"); vhdl.set_body ("out_ACCESS_ENTITY_"+toString(i)+" <= access_entity_"+toString(i)+" when in_ACCESS_VAL_"+toString(i)+" = '1' else (others => '0');"); } vhdl.set_body (""); for (uint32_t i=0; i<_param._nb_update; i++) { vhdl.set_body ("out_UPDATE_ACK_"+toString(i)+" <= '1';"); } }; }; // end namespace pseudo_lru }; // end namespace victim }; // end namespace generic }; // end namespace behavioural }; // end namespace morpheo #endif