----------------------------------------------------------------------------------
-- Company:        CERN, BE-CO-HT
-- Engineer:       Carlos Gil Soriano
-- 
-- Create Date:    09:58:06 10/12/2011 
-- Design Name:    HDL trigger top
-- Module Name:    trigger - Behavioral 
-- Project Name:   CTDAH
-- Target Devices: Spartan 6
-- Tool versions: 
-- Description:    This is the wishbone trigger which receives a input
--                 and outputs a trigger signal for the pulse converter.
--                 It internally debounces the inputs and control the output
--                 driver.
--                 The registers it has can be modified via wishbone access.
-- Dependencies:   none
--
-- Revision: 
-- Revision 0.1
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity trigger_top is
  port (
         pulse_i    : in   STD_LOGIC;
         pulse_o    : out  STD_LOGIC;

         led_o      : out  STD_LOGIC;

         utc_i      : in   STD_LOGIC_VECTOR(95 downto 0);

         wb_rst_i   : in   STD_LOGIC;		
         wb_clk     : in   STD_LOGIC;		
         wb_stb_i   : in   STD_LOGIC;
         wb_cyc_i   : in   STD_LOGIC;
         wb_ack_o   : out  STD_LOGIC;
         wb_err_o   : out  STD_LOGIC;
         wb_rty_o   : out  STD_LOGIC;
         wb_we_i    : in   STD_LOGIC;		
         wb_sel_i   : in   STD_LOGIC_VECTOR (3  downto 0);
         wb_data_i  : in   STD_LOGIC_VECTOR (31 downto 0);
         wb_data_o  : out  STD_LOGIC_VECTOR (31 downto 0);
         wb_addr_i  : in   STD_LOGIC_VECTOR (2  downto 0)
       );
end trigger_top;


architecture Behavioral of trigger_top is

  constant c_RAM_SIZE               : UNSIGNED(15 downto 0) := X"0100";
  constant c_MAX_GLITCH_STAGES      : INTEGER := 6;
  constant c_DEFAULT_GLITCH_MASK    : UNSIGNED(c_MAX_GLITCH_STAGES-1 downto 0) := "000011";--(others => '1'); 
-- Let's assume that a 20MHz clock is used in wishbone
  constant c_MIN_PULSE_LENGTH       : INTEGER := 20;
  constant c_MAX_PULSE_LENGTH       : INTEGER := 40;
  constant c_DEFAULT_PULSE_LENGTH   : INTEGER := 30;
  constant c_TAGS_DATA_WIDTH        : INTEGER := 96;


  signal STATUS_s : STD_LOGIC_VECTOR (31 downto 0);
  signal CTR0_s   : STD_LOGIC_VECTOR (31 downto 0);
  signal CTR1_s   : STD_LOGIC_VECTOR (31 downto 0);
  signal RAM0_s   : STD_LOGIC_VECTOR (31 downto 0);
  signal RAM1_s   : STD_LOGIC_VECTOR (31 downto 0);
  signal RAM2_s   : STD_LOGIC_VECTOR (31 downto 0);

  signal write_tt_s     : STD_LOGIC;

  signal ramTT_s  : STD_LOGIC_VECTOR(c_TAGS_DATA_WIDTH - 1 downto 0);   
  signal ramID_s  : STD_LOGIC_VECTOR(31 downto 0);

  component trigger_regs 
    generic(
    g_MAX_GLITCH_STAGES     : INTEGER := c_MAX_GLITCH_STAGES;
    g_DEFAULT_GLITCH_MASK   : UNSIGNED (c_MAX_GLITCH_STAGES - 1 downto 0) := c_DEFAULT_GLITCH_MASK;
    g_MIN_PULSE_LENGTH      : INTEGER := c_MIN_PULSE_LENGTH;
    g_MAX_PULSE_LENGTH      : INTEGER := c_MAX_PULSE_LENGTH;
    g_DEFAULT_PULSE_LENGTH  : INTEGER := c_DEFAULT_PULSE_LENGTH
  );
  port (
         wb_rst_i   : in   STD_LOGIC;		
         wb_clk     : in   STD_LOGIC;		
         wb_stb_i   : in   STD_LOGIC;
         wb_cyc_i   : in   STD_LOGIC;
         -- Terminating signals
         wb_ack_o   : out  STD_LOGIC;
         wb_err_o   : out  STD_LOGIC;
         wb_rty_o   : out  STD_LOGIC;
         wb_we_i    : in   STD_LOGIC;		
         wb_sel_i   : in   STD_LOGIC_VECTOR (3  downto 0);
         wb_data_i  : in   STD_LOGIC_VECTOR (31 downto 0);
         wb_data_o  : out  STD_LOGIC_VECTOR (31 downto 0);
         wb_addr_i  : in   STD_LOGIC_VECTOR (2  downto 0);

         STATUS_o   : out  STD_LOGIC_VECTOR (31 downto 0);
         CTR0_o     : out  STD_LOGIC_VECTOR (31 downto 0);
         CTR1_o     : out  STD_LOGIC_VECTOR (31 downto 0);
         RAM0_o     : out  STD_LOGIC_VECTOR (31 downto 0);
         RAM1_i     : in   STD_LOGIC_VECTOR (31 downto 0);
         RAM2_o     : out  STD_LOGIC_VECTOR (31 downto 0);

         ramTT_i    : in   STD_LOGIC_VECTOR (95 downto 0);
         ramID_i    : in   STD_LOGIC_VECTOR (31 downto 0)
       );
  end component;


  component trigger_core is
    port (
           pulse_i    : in   STD_LOGIC;
           pulse_o    : out  STD_LOGIC;

           led_o      : out  STD_LOGIC;

           wb_rst_i   : in   STD_LOGIC;
           wb_clk     : in   STD_LOGIC;

           write_tt_o : out  STD_LOGIC;

           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_i     : in   STD_LOGIC_VECTOR (31 downto 0);
           RAM2_i     : in   STD_LOGIC_VECTOR (31 downto 0)
         );
  end component;

  component 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(c_TAGS_DATA_WIDTH - 1 downto 0);           
           ramID_o      : out  STD_LOGIC_VECTOR(31 downto 0)
         );
  end component;

begin


  registers: trigger_regs
  port map(
            wb_rst_i    => wb_rst_i,
            wb_clk      => wb_clk,
            wb_stb_i    => wb_stb_i,
            wb_cyc_i    => wb_cyc_i,
            wb_ack_o    => wb_ack_o,
            wb_err_o    => wb_err_o,
            wb_rty_o    => wb_rty_o,
            wb_we_i     => wb_we_i,
            wb_sel_i    => wb_sel_i,
            wb_data_i   => wb_data_i,
            wb_data_o   => wb_data_o,
            wb_addr_i   => wb_addr_i,

            STATUS_o    => STATUS_s,
            CTR0_o      => CTR0_s,
            CTR1_o      => CTR1_s,
            RAM0_o      => RAM0_s,
            RAM1_i      => RAM1_s,
            RAM2_o      => RAM2_s,

            ramTT_i     => ramTT_s,            
            ramID_i     => ramID_s
          );

  core: trigger_core
  port map(
            pulse_i     => pulse_i, 
            pulse_o     => pulse_o,

            led_o       => led_o,

            wb_clk      => wb_clk,
            wb_rst_i    => wb_rst_i,

            write_tt_o  => write_tt_s,

            STATUS_i    => STATUS_s,
            CTR0_i      => CTR0_s,
            CTR1_i      => CTR1_s,
            RAM0_i      => RAM0_s,
            RAM1_i      => RAM1_s,         
            RAM2_i      => RAM2_s          
            );

  ram_handler: TT_RAMhandler
  port map(
            utc_i            => utc_i,
            STATUS_i         => STATUS_s,
            CTR0_i           => CTR0_s,
            CTR1_i           => CTR1_s,
            RAM0_i           => RAM0_s,
            RAM1_o           => RAM1_s,
            RAM2_i           => RAM2_s,
            wb_clk           => wb_clk,
            wb_rst_i         => wb_rst_i,
            write_tt_i       => write_tt_s,
            ramTT_o          => ramTT_s,             
            ramID_o          => ramID_s
          );


end Behavioral;
