---------------------------------------------------------------------------
-- NDT Solutions Ltd. Proprietary Information
-- Company Confidential
-- Copyright 2006
--
-- Filename: OversampleTrigHold.vhd
-- Language: VHDL '93
-- Project:  Digitiser Card DSP FPGA
--
-- Design Description:
-- Module to capture triggers from first oversample and hold for subseqent samples
--
---------------------------------------------------------------------------

library IEEE;
use IEEE.Std_Logic_1164.all;
use IEEE.Std_Logic_Arith.all;

library work;
use work.DspFpgaPkg.all;

entity OversampleTrigHold is
  port(pnReset         : in  std_ulogic;
       pADC_2xClk      : in  std_ulogic;
       pSampleEn       : in  std_ulogic;
       pNewSequence    : in  std_ulogic;
       pAScanActive    : in  std_ulogic;
       pTriggersIn     : in  std_logic_vector(15 downto 0);
       pNoTriggersIn   : in  std_logic_vector(15 downto 0);
       pTriggersOut    : out std_logic_vector(15 downto 0);
       pNoTriggersOut  : out std_logic_vector(15 downto 0));
end entity OversampleTrigHold;


architecture Rtl of OversampleTrigHold is

  signal NewSequence     : std_ulogic;
  signal OverSample0     : std_ulogic;
  signal DelayedSampleEn : std_ulogic;
  signal TimeCount       : std_logic_vector(15 downto 0);

  type tGateFireTime is array(0 to 5) of std_logic_vector(15 downto 0);
  signal GateFireTime   : tGateFireTime;

  signal TimeTriggers   : std_logic_vector(15 downto 0);
  signal TimeNoTriggers : std_logic_vector(15 downto 0);

begin
  
  GenOverSample0: process(pnReset, pADC_2xClk)
    variable vAScanActiveDel: std_ulogic;
  begin
    if pnReset = '0' then
      NewSequence <= '0';
      OverSample0 <= '0';
      vAScanActiveDel := '0';
    elsif rising_edge(pADC_2xClk) then
      if pNewSequence = '1' then
        NewSequence <= '1';
      elsif pAscanActive = '1' and vAScanActiveDel = '0' then -- start of A-Scan
        NewSequence <= '0';
      end if;
      if NewSequence = '1' and pAScanActive = '0' then
        OverSample0 <= '1';
      elsif pAscanActive = '0' and vAScanActiveDel = '1' then -- end of A-Scan
        OverSample0 <= '0';
      end if;
      vAScanActiveDel := pAscanActive;
    end if;
  end process GenOverSample0;
  

  GenTimeCount: process(pnReset, pADC_2xClk)
  begin
    if pnReset = '0' then
      TimeCount   <= (others => '1');
      DelayedSampleEn <= '0';
    elsif rising_edge(pADC_2xClk) then
      if DelayedSampleEn = '1' then
        if pTriggersIn(15) = '1' then
          -- Start count when main delayed trigger fires
          TimeCount <= (others => '0');

        elsif TimeCount /= "1111111111111111" then
          TimeCount <= unsigned(TimeCount) + 1;
        end if;
      end if;

      DelayedSampleEn <= pSampleEn;
    end if;
  end process GenTimeCount;


  -- Log the fire time for each gate for first oversample
  LogGateFireTimes: process(pnReset, pADC_2xClk)
  begin
    if pnReset = '0' then
      for Count in 0 to 5 loop
        GateFireTime(Count) <= (others => '0');
        TimeNoTriggers(Count) <= '0';
      end loop;

    elsif rising_edge(pADC_2xClk) then
      if DelayedSampleEn = '1' and OverSample0 = '1' then
        for Count in 0 to 5 loop
          if pTriggersIn(15) = '1' or pNoTriggersIn(Count) = '1' then
            GateFireTime(Count) <= (others => '0');
          else
            if pTriggersIn(Count) = '1' then
              -- This is a trigger event, get the new fire time
              GateFireTime(Count) <= unsigned(TimeCount) - 1;
            end if;
          end if;
          TimeNoTriggers(Count) <= pNoTriggersIn(Count);
        end loop;
      end if;
    end if;
  end process LogGateFireTimes;


  -- generate time triggers based on first oversample gate fire times
  GenTimeTriggers: process(pnReset, pADC_2xClk)
  begin
    if pnReset = '0' then
      TimeTriggers <= (others => '0');

    elsif rising_edge(pADC_2xClk) then
      TimeTriggers <= (others => '0');
      if pSampleEn = '1' then
        for Count in 0 to 5 loop
          if TimeCount = GateFireTime(Count) and TimeNoTriggers(Count) = '0' then
            TimeTriggers(Count) <= '1';
          else
            TimeTriggers(Count) <= '0';
          end if;
        end loop;
      end if;
    end if;
  end process GenTimeTriggers;

  pTriggersOut(5 downto 0) <= pTriggersIn(5 downto 0) when OverSample0 = '1' else TimeTriggers(5 downto 0);
  pTriggersOut(15 downto 6) <= pTriggersIn(15 downto 6);
  pNoTriggersOut(5 downto 0) <= pNoTriggersIn(5 downto 0) when OverSample0 = '1' else TimeNoTriggers(5 downto 0);
  pNoTriggersOut(15 downto 6) <= pNoTriggersIn(15 downto 6);

end architecture Rtl;