--------------------------------------------------------------------------------
-- Title   : Top-up gating top file
-- Project : TimEX3
--------------------------------------------------------------------------------
-- Description : Top-up gating top sheet block
--               output(2) : negative gating window
--               output(3) : negative beam lost
--               output(4) : negative (beam lost + gating) window
--------------------------------------------------------------------------------
-- File     : topup_top.vhdl
-- Revision : x.x.x
-- Created  : October 26, 2012
-- Updated  : November 06, 2013
--------------------------------------------------------------------------------
-- Author       : Jean-Paul Ricaud
-- Organization : Synchrotron Soleil
-- Web          : http://www.synchrotron-soleil.fr
-- Email        : jean-paul.ricaud@synchrotron-soleil.fr
--------------------------------------------------------------------------------
-- Copyright (C) 2012 - 2013 Synchrotron Soleil
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Modifications :
--   Version 1.4.1 ; October 29 2013 ; Jean-Paul Ricaud
--     * Added a bit in the status register for top-up gating window active
--     * Renamed some signals ; added comments
--
--------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

--------------------------------------------------------------------------------
--------------------------------- ENTITY ---------------------------------------
--------------------------------------------------------------------------------
entity topup_top is
  port (
    p_topUp_inTTL        : in  std_logic_vector (1 downto 0);
    p_topUp_outTTL       : out std_logic_vector (4 downto 0);
    p_topUp_outPECL      : out std_logic_vector (4 downto 0);
    p_topUp_clk1kHz      : in  std_logic;
    p_topUp_clk500mHz    : in  std_logic;
    p_topUp_clk60MHz     : in  std_logic;
    p_beamLost_holdOff   : in  std_logic_vector (31 downto 0);
    p_beamLost_holdOn    : in  std_logic_vector (31 downto 0);
    p_topUp_gateHoldOff  : in  std_logic_vector (31 downto 0);
    p_topUp_gateWidth    : in  std_logic_vector (31 downto 0);
    p_topUp_csw          : in  std_logic_vector (3  downto 0);
    p_topUp_reset        : in  std_logic;
    p_topup_topUpGate    : out std_logic_vector (1 downto 0); -- top-up gate
                                                              -- (1 : top-up gate window active)
    p_topup_beamLostGate : out std_logic_vector (1 downto 0); -- beam lost gate
                                                              -- (1 : beam lost window active)
    -- LED(0) = red ; LED(1) = green
    p_topUp_LED          : out std_logic_vector (1 downto 0)
   );
end entity topup_top;

--------------------------------------------------------------------------------
------------------------------- ARCHITECTURE -----------------------------------
--------------------------------------------------------------------------------
architecture rtl_topup_top of topup_top is
  ------------------------------------------------------------------------------
  -- constant
  ------------------------------------------------------------------------------

  ------------------------------------------------------------------------------
  -- signal
  ------------------------------------------------------------------------------
  signal s_beamGate   : std_logic; -- Beam lost gate (hold on time)
  signal s_in1        : std_logic;
  signal s_in0        : std_logic;
  signal s_gateWindow : std_logic; -- top-up gate (hold on time);
  signal s_injError   : std_logic;

  ------------------------------------------------------------------------------
  -- Attributes
  ------------------------------------------------------------------------------

  attribute KEEP : string;
  attribute KEEP of s_in0, s_in1 : signal is "TRUE";

  ------------------------------------------------------------------------------
  --------------------------------- Main ---------------------------------------
  ------------------------------------------------------------------------------
  begin

    -- Gating of the top-up injection
    topup_gating : entity work.topup_gating (rtl_topup_gating)
      port map (
        p_clk1kHz     => p_topUp_clk1kHz,
        p_clk60MHz    => p_topUp_clk60MHz,
        p_inTTL(0)    => p_topUp_inTTL(0),
        p_inTTL(1)    => s_in1,
        p_gateWindow  => s_gateWindow, -- top-up gate (window active);
        p_gateHoldOff => p_topUp_gateHoldOff,
        p_gateWidth   => p_topUp_gateWidth,
        p_csw         => p_topUp_csw(3 downto 2),
        p_reset       => p_topUp_reset
      );

    -- Monitoring the beam lost
    topup_beamlost : entity work.topup_beamlost (rtl_topup_beamlost)
      port map (
        p_clk1kHz              => p_topUp_clk1kHz,
        p_clk60MHz             => p_topUp_clk60MHz,
        p_inTTL(0)             => not s_gateWindow,
        p_inTTL(1)             => s_in1,
        p_beamLostHoldOffDelay => p_beamLost_holdOff,
        p_beamLostHoldOnDelay  => p_beamLost_holdOn,
        p_csw                  => p_topUp_csw(1 downto 0),
        p_reset                => p_topUp_reset,
        p_beamGate             => s_beamGate
      );

    -- Toggle the output during the gating of an injection or a beam lost
    topup_injError : entity work.topup_injError (rtl_topup_injError)
      port map (
        p_clk1kHz    => p_topUp_clk1kHz,
        p_gateWindow => s_gateWindow, -- top-up gate (hold on time);
        p_beamLost   => s_beamGate,
        p_injError   => s_injError
      );

    -- Set a bit during 2s after a gating of an injection or a beam lost
    topup_stateBit : entity work.topup_stateBit (rtl_topup_stateBit)
      port map (
        p_clk500mHz        => p_topUp_clk500mHz,
        p_gateWindow       => s_gateWindow, -- top-up gate (hold on time);
        p_beamLost         => s_beamGate,
        p_stateBitGate     => p_topup_topUpGate(1),
        p_stateBitBeamLost => p_topup_beamLostGate(1),
        p_reset            => p_topUp_reset
      );

    -- Turn on the LEDs according to the top-up monitiring
    topup_leds : entity work.topup_leds (rtl_topup_leds)
      port map (
        p_clk500mHz => p_topUp_clk500mHz,
        p_State     => s_gateWindow, -- top-up gate (hold on time);
        p_Error     => s_beamGate,
        p_ledOut    => p_topUp_LED
      );

  ------------------------------------------------------------------------------
  ------------------------------------------------------------------------------
  s_in0 <= not p_topup_inTTL(1);
  s_in1 <= not s_in0;

  p_topUp_outTTL  (1 downto 0) <= "00"; -- not used
  p_topUp_outTTL  (4 downto 2) <= (not s_injError) & (not s_beamGate) & (not s_gateWindow);
  p_topUp_outPECL (4 downto 0) <= "00000";

  p_topup_topUpGate(0)    <= s_gateWindow; -- top-up gate (hold on time)
  p_topup_beamLostGate(0) <= s_beamGate;   -- beam lost gate (hold on time)

end architecture rtl_topup_top;
