--******************************************************************************
--* @short   Vector of 16-bit Error counters: 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.2 $
--* @date    $Date: 2005/01/20 11:02:17 $x
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use work.VMEMux.all;

entity ErrorCounterVec is
  generic (
    reset_address : integer := 0;
    counter_base_address : integer := 0); -- VME address of this instance

  port (
    -- data port
    error_bits   : in std_logic_vector;
    
    -- VME port
    vme_addr     : in    std_logic_vector;  -- leave unconstrained 
    vme_data     : inout std_logic_vector(15 downto 0);
    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 ErrorCounterVec;


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

architecture behavioral of ErrorCounterVec is

  signal reset_vec : std_logic_vector(15 downto 0);
  signal vme_data_out_i : TVMEData_vec (0 to error_bits'high+1);
  signal vme_en_out_i   : TVMEEnable_vec (0 to error_bits'high+1);
  
begin  -- behavioral

  -----------------------------------------------------------------------------
  --* the counter reset register
  -----------------------------------------------------------------------------
  counter_reset_reg: entity work.VMEWritePulseReg
    generic map (
      my_vme_base_address => reset_address )
    port map (
      data_pulse   => reset_vec,        
      reset        => reset,
      
      vme_addr => vme_addr, vme_data => vme_data, vme_en => vme_en, vme_wr => vme_wr,
      vme_data_out => vme_data_out_i(error_bits'high+1),
      vme_en_out   => vme_en_out_i(error_bits'high+1),
      vme_clk      => clk);

  -----------------------------------------------------------------------------
  --* instantiate the counters
  -----------------------------------------------------------------------------

  counters: for i in error_bits'range generate
  begin  -- generate counters
    counter: entity work.ErrorCounter16bit
      generic map (
        my_vme_base_address => counter_base_address+2*i)
      port map (
        count_enable  => error_bits(i),
        counter_reset => reset_vec(0),
        vme_addr      => vme_addr,
        vme_en        => vme_en,
        vme_wr        => vme_wr,
        vme_data_out  => vme_data_out_i(i),
        vme_en_out    => vme_en_out_i(i),
        clk           => clk,
        reset         => reset);
    
  end generate counters;

  -----------------------------------------------------------------------------
  -- multiplex VME outputs
  -----------------------------------------------------------------------------
  mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out, vme_en_out);

end behavioral;