----------------------------------------------------------------------------------
-- Company:        CERN, BE-CO-HT
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    08:49:17 11/30/2011 
-- Design Name:    Time-tagging RAM handler
-- Module Name:    TT_RAMhandler - Behavioral 
-- Project Name:   CTDAH
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description:    This module handles the way the RAM is accessed
--
-- Dependencies:   none
--
-- Revision: 
-- Revision 0.1
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity TT_RAMhandler is
  generic(
           g_TAGS_DATA_WIDTH : INTEGER := 96 
         );
  port (
         utc_i        : in   STD_LOGIC_VECTOR(g_TAGS_DATA_WIDTH - 1 downto 0);

         STATUS_i     : in  STD_LOGIC_VECTOR (31 downto 0);
         CTR0_i       : in  STD_LOGIC_VECTOR (31 downto 0);
         CTR1_i       : in  STD_LOGIC_VECTOR (31 downto 0);
         RAM0_i       : in  STD_LOGIC_VECTOR (31 downto 0);
         RAM1_o       : out STD_LOGIC_VECTOR (31 downto 0);
         RAM2_i       : in  STD_LOGIC_VECTOR (31 downto 0);

         wb_clk       : in   STD_LOGIC;
         wb_rst_i     : in   STD_LOGIC;

         write_tt_i       : in   STD_LOGIC;
         ramTT_o      : out  STD_LOGIC_VECTOR(g_TAGS_DATA_WIDTH - 1 downto 0);
         ramID_o      : out  STD_LOGIC_VECTOR(31 downto 0)
       );

end TT_RAMhandler;

architecture Behavioral of TT_RAMhandler is

  
  constant  c_TAGS_ADDR_WIDTH : INTEGER := 8; 
  constant  c_TAGS_ADDR_SIZE  : INTEGER := 256;

  constant  c_RAMTT_DATA_WIDTH  : INTEGER := g_TAGS_DATA_WIDTH; 
  constant  c_RAMID_DATA_WIDTH  : INTEGER := 32; 
  constant  c_RAMBIT_DATA_WIDTH : INTEGER := 2;

  signal write_tt_done_s  : STD_LOGIC;
  signal dout_RAMTT       : STD_LOGIC_VECTOR (c_RAMTT_DATA_WIDTH - 1 downto 0);
  signal dout_RAMID       : STD_LOGIC_VECTOR (c_RAMID_DATA_WIDTH - 1 downto 0);

  signal clkb_s           : STD_LOGIC;
  signal rstb_s           : STD_LOGIC;

  signal CWA    : STD_LOGIC_VECTOR(15 downto 0);
  signal CRA    : STD_LOGIC_VECTOR(15 downto 0);

  component gc_RAM
    generic(
    g_DATA_WIDTH : INTEGER;
    g_ADDR_WIDTH : INTEGER;
    g_ADDR_SIZE  : INTEGER
  );
  port(
        clka   : in  STD_LOGIC;
        wea    : in  STD_LOGIC;
        addra  : in  STD_LOGIC_VECTOR(g_ADDR_WIDTH - 1 downto 0);
        dina   : in  STD_LOGIC_VECTOR(g_DATA_WIDTH - 1 downto 0);
        clkb   : in  STD_LOGIC;
        rstb   : in  STD_LOGIC;
        addrb  : in  STD_LOGIC_VECTOR(g_ADDR_WIDTH - 1 downto 0);
        doutb  : out STD_LOGIC_VECTOR(g_DATA_WIDTH - 1 downto 0)
      );
  end component;

begin

  clkb_s <= wb_clk and RAM0_i(7);
  rstb_s <= wb_rst_i or STATUS_i(1) or STATUS_i(5); 
  RAM1_o <= CWA & CRA;

  RAMTT_256: gc_RAM
  generic map(
               g_DATA_WIDTH => c_RAMTT_DATA_WIDTH,
               g_ADDR_WIDTH => c_TAGS_ADDR_WIDTH,
               g_ADDR_SIZE  => c_TAGS_ADDR_SIZE
             )
  port map(
            clka        => wb_clk,
            wea         => RAM0_i(7),
            addra       => CWA(7 downto 0),
            dina        => utc_i,
            clkb        => clkb_s,
            rstb        => rstb_s,
            addrb       => CRA(7 downto 0),
            doutb       => dout_RAMTT
          );

  RAMID_256: gc_RAM
  generic map(
               g_DATA_WIDTH => c_RAMID_DATA_WIDTH,
               g_ADDR_WIDTH => c_TAGS_ADDR_WIDTH,
               g_ADDR_SIZE  => c_TAGS_ADDR_SIZE
             )
  port map(
            clka        => wb_clk,
            wea         => RAM0_i(7),
            addra       => CWA(7 downto 0),
            dina(15 downto 0)    => (others => '0'),
            dina(31 downto 16)   => STATUS_i(31 downto 16),
            clkb        => clkb_s,
            rstb        => rstb_s,
            addrb       => CRA(7 downto 0),
            doutb       => dout_RAMID
          );


  proc_rd: process(wb_clk)
  begin
    if rising_edge(wb_clk) then
      if wb_rst_i = '1' or STATUS_i(1) = '1' then
      -- Trigger clear and reset
        CWA           <= (others => '0');     
        CRA           <= (others => '0');
      else
      end if;
    else
    end if;
  end process;

end Behavioral;
