%------------------------------------------------------------------------------
% $Id: document-morpheo-vhdl_generation-fr-05_01_registerfile.tex 100 2009-01-08 13:06:27Z rosiere $
%------------------------------------------------------------------------------

\subSection{Banc de Registres Monolithique}

\subsubSection{Fichier RegisterFile\_Monolithic\_vhdl.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={RegisterFile\_Monolithic\_vhdl.cpp}]
void RegisterFile_Monolithic::vhdl (void)
{
  Vhdl * vhdl = new Vhdl (_name);

  _interfaces->set_port     (vhdl);
  _component ->vhdl_instance(vhdl);

  vhdl_declaration (vhdl);
  vhdl_body        (vhdl);

  vhdl->generate_file();

  delete vhdl;
};
\end{lstlisting}


\subsubSection{Fichier RegisterFile\_Monolithic\_vhdl\_declaration.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={RegisterFile\_Monolithic\_vhdl\_declaration.cpp}]
void RegisterFile_Monolithic::vhdl_declaration (Vhdl * & vhdl)
{
  vhdl->set_type ("Tregfile", "array " + std_logic_range(_param->_nb_word,true)+
                              " of "+
                              std_logic(_param->_size_word));

  vhdl->set_signal ("reg_DATA", "Tregfile");
};
\end{lstlisting}

\subsubSection{Fichier RegisterFile\_Monolithic\_vhdl\_body.cpp}

\lstparam{C++}
\begin{lstlisting}[caption={RegisterFile\_Monolithic\_vhdl\_body.cpp}]
void RegisterFile_Monolithic::vhdl_body (Vhdl * & vhdl)
{
  vhdl->set_body   (0,"");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_comment(0," Ack");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_body   (0,"");

  for (uint32_t i = 0; i < _param->_nb_port_read; i++)
    vhdl->set_body   (0,"out_READ_"+toString(i)+"_ACK  <= '1';");
  for (uint32_t i = 0; i < _param->_nb_port_write; i++)
    vhdl->set_body   (0,"out_WRITE_"+toString(i)+"_ACK <= '1';");

  vhdl->set_body   (0,"");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_comment(0," Read RegisterFile");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_body   (0,"");
  
  for (uint32_t i = 0; i < _param->_nb_port_read; i++)
    {
      std::string str_address;
      if (_param->_have_port_address)
        str_address = "conv_integer(in_READ_"+toString(i)+"_ADDRESS)";
      else
        str_address = "0";

      vhdl->set_body   (0,"out_READ_"+toString(i)+"_DATA <= reg_DATA ("+str_address+
                           ") when in_READ_"+toString(i)+"_VAL = '1' else "+
                           std_logic_others(_param->_size_word,0)+";");
    }

  vhdl->set_body   (0,"");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_comment(0," Write RegisterFile");
  vhdl->set_comment(0,"---------------------------------------------------");
  vhdl->set_body   (0,"");

  vhdl->set_body   (0,"RegisterFile_write: process (in_CLOCK)");
  vhdl->set_body   (0,"begin  -- process RegisterFile_write");
  vhdl->set_body   (1,"if in_CLOCK'event and in_CLOCK = '1' then");
  
  for (uint32_t i = 0; i < _param->_nb_port_write; i++)
    {
      std::string str_address;
      if (_param->_have_port_address)
        str_address = "conv_integer(in_WRITE_"+toString(i)+"_ADDRESS)";
      else
        str_address = "0";

      vhdl->set_body   (2,"if (in_WRITE_"+toString(i)+"_VAL = '1') then");
      vhdl->set_body   (3,"reg_DATA("+str_address+") <= in_WRITE_"+toString(i)+"_DATA;");
      vhdl->set_body   (2,"end if;");
    }

  vhdl->set_body   (1,"end if;");
  vhdl->set_body   (0,"end process RegisterFile_write;");
};
\end{lstlisting}

\subsubSection{Fichier RegisterFile\_Monolithic.vhdl}

\lstparam{VHDL}
\begin{lstlisting}[caption={RegisterFile\_Monolithic.cpp}]
  library ieee;
  use ieee.numeric_bit.all;       
  use ieee.numeric_std.all;       
  use ieee.std_logic_1164.all;    
  use ieee.std_logic_arith.all;   
  use ieee.std_logic_misc.all;    
--use ieee.std_logic_signed.all;  
  use ieee.std_logic_unsigned.all;
--use ieee.std_logic_textio.all;  


library work;
use work.RegisterFile_Monolithic_Pack.all;


entity RegisterFile_Monolithic is
  port ( in_CLOCK          : in  std_logic;
         in_NRESET         : in  std_logic;
         in_READ_0_VAL     : in  std_logic;
        out_READ_0_ACK     : out std_logic;
         in_READ_0_ADDRESS : in  std_logic_vector(8 downto 0);
        out_READ_0_DATA    : out std_logic_vector(31 downto 0);
         in_WRITE_0_VAL    : in  std_logic;
        out_WRITE_0_ACK    : out std_logic;
         in_WRITE_0_ADDRESS: in  std_logic_vector(8 downto 0);
         in_WRITE_0_DATA   : in  std_logic_vector(31 downto 0)
       );
end RegisterFile_Monolithic;

architecture behavioural of RegisterFile_Monolithic is
  type Tregfile   is array (511 downto 0) of std_logic_vector(31 downto 0);

  signal reg_DATA : Tregfile;

begin
  -----------------------------------------------------
  -- Ackitement
  -----------------------------------------------------
  
  out_READ_0_ACK  <= '1';
  out_WRITE_0_ACK <= '1';
  
  -----------------------------------------------------
  -- Read RegisterFile
  -----------------------------------------------------
  
  out_READ_0_DATA <= reg_DATA (conv_integer(in_READ_0_ADDRESS)) 
                     when in_READ_0_VAL = '1'
                     else (others => '0');
  
  -----------------------------------------------------
  -- Write RegisterFile
  -----------------------------------------------------
  
  RegisterFile_write: process (in_CLOCK)
  begin  -- process RegisterFile_write
    if in_CLOCK'event and in_CLOCK = '1' then
      if (in_WRITE_0_VAL = '1') then
        reg_DATA(conv_integer(in_WRITE_0_ADDRESS)) <= in_WRITE_0_DATA;
      end if;
    end if;
  end process RegisterFile_write;
end behavioural;
\end{lstlisting}
