--------------------------------------------------------------------------------
-- Title   : Leds
-- Project : TimEX3
--------------------------------------------------------------------------------
-- Description : Leds management
--
--            | OFF                 | ON                  | BLINKING
--      ======|=====================|=====================|=====================
--      GREEN | FPGA not configured | OK                  | synchro pulse
--            |                     |                     | detected
--      ======|=====================|=====================|=====================
--      RED   | OK                  | no synchro pulse    |
--            |                     | for more than n mn  |
--      ======|=====================|=====================|=====================
--
--------------------------------------------------------------------------------
-- File     : freqDIV_leds.vhdl
-- Revision : x.x.x
-- Created  : February 03, 2014
-- Updated  : February 03, 2014
--------------------------------------------------------------------------------
-- Author       : Jean-Paul Ricaud
-- Organization : Synchrotron Soleil
-- Web          : http://www.synchrotron-soleil.fr
-- Email        : jean-paul.ricaud@synchrotron-soleil.fr
--------------------------------------------------------------------------------
-- Copyright (C) 2012 - 2014 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 :
--------------------------------------------------------------------------------

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

library work;
use work.registers_init.all;

--------------------------------------------------------------------------------
--------------------------------- ENTITY ---------------------------------------
--------------------------------------------------------------------------------
entity freqDIV_leds is
  port (
    p_inTTL             : in  std_logic; -- input TTL
    p_clk1kHz           : in  std_logic;
    p_clk500mHz         : in  std_logic;
    p_clk60MHz          : in  std_logic;
    p_missingPulseDelay : in  std_logic_vector (31 downto 0);
    p_csw               : in  std_logic;
    p_reset             : in  std_logic;
    p_led               : out std_logic_vector (1 downto 0)
  );
end entity freqDIV_leds;

--------------------------------------------------------------------------------
------------------------------- ARCHITECTURE -----------------------------------
--------------------------------------------------------------------------------
architecture rtl_freqDIV_leds of freqDIV_leds is

  ------------------------------------------------------------------------------
  -- constant
  ------------------------------------------------------------------------------
  constant s_cnt1max : unsigned (3 downto 0)  := "1011"; -- 5s

  ------------------------------------------------------------------------------
  -- signal
  ------------------------------------------------------------------------------
  signal s_cnt1       : unsigned (3  downto 0); -- counter
  signal s_cnt2       : unsigned (31 downto 0); -- counter
  signal s_cnt2max    : unsigned (31 downto 0); -- max delay
  signal s_greenLedON : std_logic;
  signal s_blink      : std_logic;
  signal s_rstCNT     : std_logic; -- reset the conter after a software delay update
  signal s_start      : std_logic;
  signal s_stop       : std_logic;
  signal s_hold1      : std_logic;
  signal s_hold2      : std_logic;

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


  -- Green LED
  -- The green LED is blinked for 5s after a reset or after a input pulse is
  -- détected. It remains ON in other cases.
  process (p_reset, p_inTTL, p_clk500mHz)
  begin
    if ((p_inTTL = '1') or (p_reset = '1')) then
      s_cnt1       <= (OTHERS => '0');
      s_greenLedON <= '1'; -- green LED ON
      s_blink      <= '1'; -- blink the green LED
    elsif (rising_edge(p_clk500mHz)) then
      if (s_blink = '1') then
        if (s_cnt1 < s_cnt1max) then
          s_cnt1       <= s_cnt1 + 1;
          s_greenLedON <= not s_greenLedON; -- blink the green LED
          s_blink      <= '1';              -- keep blinking
        else
          s_cnt1       <= s_cnt1; -- keep the max value
          s_greenLedON <= '1';    -- green LED ON
          s_blink      <= '0';    -- stop blinking
        end if;
      else
        s_cnt1       <= s_cnt1; -- keep the max value
        s_greenLedON <= '1';    -- green LED ON
        s_blink      <= '0';    -- stop blinking
      end if;
    end if;
  end process;

  -- Red LED
  -- The red LED is off after a reset. It gos ON if no input signal is detected
  -- after n mn.
  process (p_reset, p_inTTL, s_stop)
  begin
    if ((s_stop = '1') or (p_reset = '1')) then
      s_start <= '0';
    elsif (rising_edge(p_inTTL)) then
      s_start <= '1';
    end if;
  end process;

  process (p_reset, s_start, p_clk1kHz)
  begin
    if ((s_start = '0') or (p_reset = '1')) then
      s_hold1 <= '0';
      s_hold2 <= '0';
      s_stop  <= '0';
    elsif (falling_edge(p_clk1kHz)) then
      s_hold1 <= '1';
      s_hold2 <= s_hold1;
      s_stop  <= s_hold2;
    end if;
  end process;

  process (p_reset, s_stop, s_rstCNT, p_clk1kHz)
  begin
    if ((s_stop = '1') or (p_reset = '1') or (s_rstCNT = '1')) then
      s_cnt2    <= (OTHERS => '0');
      p_led(0)  <= '0'; -- red LED OFF
    elsif (rising_edge(p_clk1kHz)) then
      if (s_cnt2 < s_cnt2max) then
        s_cnt2   <= s_cnt2 + 1;
        p_led(0) <= '0'; -- red LED OFF
      else
        s_cnt2   <= s_cnt2; -- keep the max value in case of overflow
        p_led(0) <= '1';    -- red LED ON
      end if;
    end if;
  end process;

  -- Latch from the register the maximum delay before a missing synchro pulse
  -- is signaled
  process (p_reset, p_clk60MHz)
  begin
    if (p_reset = '1') then
      s_cnt2max <= unsigned (c_wRegister_init(15));
      s_rstCNT  <= '0';
    elsif (rising_edge(p_clk60MHz)) then
      if (p_csw = '1') then
        s_cnt2max <= unsigned (p_missingPulseDelay);
        s_rstCNT  <= '1';
      else
        s_cnt2max <= s_cnt2max;
        s_rstCNT  <= '0';
      end if;
    end if;
  end process;

  ------------------------------------------------------------------------------
  ------------------------------------------------------------------------------
  p_led(1) <= s_greenLedON;

end architecture rtl_freqDIV_leds;
