--------------------------------------------------------------------------------
-- Title   : Monitoring of SPM and LPM signals
-- Project : TimEX3
--------------------------------------------------------------------------------
-- Description : The SPM and LPM signals are monotored at a frequency of 1kHz.
--               A 32 bits conter is used to save the time between two synchroization
--               pulses.
--------------------------------------------------------------------------------
-- File     : linacMON_monitoring.vhdl
-- Revision : x.x.x
-- Created  : July 10, 2013
-- Updated  : November 29, 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.6.0 ; November 29 2013 ; Jean-Paul Ricaud
--     * Monitoring now reacts on rising edge of the signal instead
--       of level
--------------------------------------------------------------------------------

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

--------------------------------------------------------------------------------
--------------------------------- ENTITY ---------------------------------------
--------------------------------------------------------------------------------
entity linacMON_monitoring is
  port (
    p_inTTL      : in  std_logic_vector (1 downto 0); -- TTL input
    p_clk1kHz    : in  std_logic;
    p_reset      : in  std_logic;
    p_SPMmonitor : out std_logic_vector (31 downto 0); -- register with the time
                                                       --  value between two SPM
    p_LPMmonitor : out std_logic_vector (31 downto 0)  -- register with the time
                                                       --  value between two LPM
  );
end linacMON_monitoring;

--------------------------------------------------------------------------------
------------------------------- ARCHITECTURE -----------------------------------
--------------------------------------------------------------------------------
architecture rtl_linacMON_monitoring of linacMON_monitoring is

  ------------------------------------------------------------------------------
  -- constant
  ------------------------------------------------------------------------------
  constant s_SPMcntmax : unsigned (31 downto 0) := X"FFFFFFFF";
  constant s_LPMcntmax : unsigned (31 downto 0) := X"FFFFFFFF";

  ------------------------------------------------------------------------------
  -- signal
  ------------------------------------------------------------------------------
  signal s_SPMcnt : unsigned (31 downto 0); -- counter
  signal s_LPMcnt : unsigned (31 downto 0); -- counter
  signal s_start  : std_logic_vector (1 downto 0);
  signal s_stop   : std_logic_vector (1 downto 0);
  signal s_hold1  : std_logic_vector (1 downto 0);
  signal s_hold2  : std_logic_vector (1 downto 0);

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

  -- SPM monitoring
  process (p_reset, p_inTTL(0), s_stop(0))
  begin
    if ((s_stop(0) = '1') or (p_reset = '1')) then
      s_start(0) <= '0';
    elsif (rising_edge(p_inTTL(0))) then
      s_start(0) <= '1';
    end if;
  end process;

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

  process (p_reset, s_stop(0), p_clk1kHz)
  begin
    if ((s_stop(0) = '1') or (p_reset = '1')) then
      s_SPMcnt <= (OTHERS => '0');
    elsif (falling_edge(p_clk1kHz)) then
      if (s_SPMcnt < s_SPMcntmax) then
        s_SPMcnt <= s_SPMcnt + 1;
      else
        s_SPMcnt <= s_SPMcnt; -- keep the max value in case of overflow
      end if;
    end if;
  end process;

  -- LPM monitoring
  process (p_reset, p_inTTL(1), s_stop(1))
  begin
    if ((s_stop(1) = '1') or (p_reset = '1')) then
      s_start(1) <= '0';
    elsif (rising_edge(p_inTTL(1))) then
      s_start(1) <= '1';
    end if;
  end process;

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

  process (p_reset, s_stop(1), p_clk1kHz)
  begin
    if ((s_stop(1) = '1') or (p_reset = '1')) then
      s_LPMcnt <= (OTHERS => '0');
    elsif (falling_edge(p_clk1kHz)) then
      if (s_LPMcnt < s_LPMcntmax) then
        s_LPMcnt <= s_LPMcnt + 1;
      else
        s_LPMcnt <= s_LPMcnt; -- keep the max value in case of overflow
      end if;
    end if;
  end process;

  ------------------------------------------------------------------------------
  ------------------------------------------------------------------------------
  p_SPMmonitor <= std_logic_vector(s_SPMcnt);
  p_LPMmonitor <= std_logic_vector(s_LPMcnt);

end rtl_linacMON_monitoring;
