--******************************************************************************
--* @short   16-bit Error counter: counts errors and can be read out via VME
--*
--*          Upon a reset the counter content is shifted to a register
--*          and the counter is reset.
--*
--******************************************************************************
--* @author  SAKULIN Hannes  <hsakulin@dsy-srv2.cern.ch>
--* @version $Revision: 1.3 $
--* @date    $Date: 2005/01/20 11:03:06 $x
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;

entity ErrorCounter16bit is
  generic (
    my_vme_base_address : integer := 0); -- VME address of this instance

  port (
    -- data port
    count_enable : in    std_logic;
    
    counter_reset : in    std_logic;
    
    -- VME port
    vme_addr     : in    std_logic_vector;  -- leave unconstrained 
    vme_en       : in    std_logic;
    vme_wr       : in    std_logic;
    vme_data_out : out   std_logic_vector;                                    
    vme_en_out   : out   std_logic;


    
    clk          : in    std_logic;
    reset        : in    std_logic);

end ErrorCounter16bit;


-------------------------------------------------------------------------------
-- Implementation
-------------------------------------------------------------------------------

architecture behavioral of ErrorCounter16bit is

  signal count_full_i   : std_logic;

  signal count          : std_logic_vector(15 downto 0);
  signal count_register : std_logic_vector(15 downto 0);
  
begin  -- behavioral

  -----------------------------------------------------------------------------
  --*  the counter
  -----------------------------------------------------------------------------
  
  counter: process (clk, reset) is
  begin  -- process counter
    if reset = '1' then
      count_register <= ( others => '0');
      count <= (others => '0');
      count_full_i <= '0';
    elsif clk'event and clk = '1' then  -- rising clock edge
      if counter_reset = '1' then
        count_register <= count;
        count <= (others => '0');
        count_full_i <= '0';
      else
        
        if count_enable = '1' and count_full_i = '0' then
          count <= std_logic_vector(to_unsigned(to_integer(unsigned(count))+1,16));
        end if;
        
      end if;
      
      if count = "1111111111111110" then
        count_full_i <= '1';
      end if;
      
    end if;
  end process counter;

  -----------------------------------------------------------------------------
  --* the VME Register
  -----------------------------------------------------------------------------
  error_reg: entity work.VMEStatusReg
    generic map (
      my_vme_base_address => my_vme_base_address)
    port map (
      data         => count_register,
      vme_addr     => vme_addr,
      vme_en       => vme_en,
      vme_wr       => vme_wr,
      vme_data_out => vme_data_out,
      vme_en_out   => vme_en_out,
      vme_clk      => clk,
      reset        => reset);

end behavioral;