---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2006
--
-- Filename: OverloadDetect.vhd
-- Language: VHDL '93
-- Project:  Pulse Receive Card Control FPGA
--
-- Design Description:
-- Output FET overload detection and disable
--
---------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_misc.all;

use work.ControlFPGA_pkg.all;

entity OverloadDetect is
  port(
    pClock        : in  std_ulogic;   -- 100MHz Clock
    pnReset       : in  std_ulogic;
    pPulse        : in  std_logic_vector(8 downto 1);
    pHVControl    : in  std_logic_vector(2 downto 0);
    pnAutoReset   : in  std_ulogic;
    pPulseDisable : out std_logic_vector(8 downto 1);
    pOverload     : out std_ulogic;
    pOverloadClear: in  std_ulogic);
end OverloadDetect;

architecture Rtl of OverloadDetect is

  signal PulseSample: std_logic_vector(8 downto 1);
  signal Overload: std_logic_vector(8 downto 1);

  signal TimeCount: unsigned(19 downto 0);
  type tPulseCount is array(8 downto 1) of unsigned(19 downto 0);
  signal PulseCount: tPulseCount;

  type tMaxOnTimeTable is array(7 downto 0) of integer range 0 to 16#FFFFF#;
  signal MaxOnTimeTable: tMaxOnTimeTable;
  signal MaxOnTime: integer range 0 to 16#FFFFF#;

  signal TimeCountZero: std_ulogic;
  signal OverloadClear: std_ulogic;

begin
  
  -- Table of Overload values for different voltage levels
  MaxOnTimeTable(0) <= 163840;
  MaxOnTimeTable(1) <= 40960;
  MaxOnTimeTable(2) <= 16777;
  MaxOnTimeTable(3) <= 9620;
  MaxOnTimeTable(4) <= 3994;
  MaxOnTimeTable(5) <= 2397;
  MaxOnTimeTable(6) <= 1712;
  MaxOnTimeTable(7) <= 1331;

  -- Sample trigger pulse with 100MHz clock
  Sample : process (pClock, pnReset) is
  begin
    if (pnReset ='0') then
      PulseSample <= (others => '0');
    elsif (pClock'event and pClock = '1') then
      PulseSample <= pPulse;
    end if;
  end process Sample;

  Counters : process (pClock, pnReset) is
  begin
    if (pnReset ='0') then
      TimeCount <= (others => '0');
      TimeCountZero <= '0';

      for i in 1 to 8 loop
        PulseCount(i) <= (others => '0');
        Overload(i) <= '0';
      end loop;

      OverloadClear <= '0';
      MaxOnTime <= 16#FFFFF#;
    elsif (pClock'event and pClock = '1') then
      TimeCount <= TimeCount + 1;
      if TimeCount = 0 then
        TimeCountZero <= '1';
      else
        TimeCountZero <= '0';
      end if;

      -- sample in 100MHz clock domain
      if pOverloadClear = '1' then  -- Latch overload clear signal
        OverloadClear <= '1';
      elsif TimeCountZero = '1' then -- only release when timeout reached
        OverloadClear <= '0';
      end if;

      MaxOnTime <= MaxOnTimeTable(conv_integer(unsigned(pHVControl)));

      for i in 1 to 8 loop
        if TimeCountZero = '1' then  -- timeout reached
          PulseCount(i) <= (others => '0');
          if pnAutoReset = '0' or OverloadClear = '1' then -- clear on AutoReset or clear received.
            OverLoad(i) <= '0';
          end if;
        elsif PulseSample(i) = '1' then
          PulseCount(i) <= PulseCount(i) + 1;
        end if;
        if PulseCount(i) = MaxOnTime then  -- check if count has reached max
          Overload(i) <= '1';
        end if;
      end loop;
    end if;
  end process Counters;

  pPulseDisable <= Overload;

  OverloadFF : process (pClock, pnReset) is
  begin
    if (pnReset ='0') then
      pOverload <= '0';
    elsif (pClock'event and pClock = '1') then
      for i in 1 to 8 loop
        if Overload(i) = '1' then
          pOverload <= '1';
        end if;
      end loop;
      if OverloadClear = '1' then
        pOverload <= '0';
      end if;
    end if;
  end process OverloadFF;

end Rtl;
