--******************************************************************************
--* @short Error Monitor for 4 x 4 bits.
--*
--* The error monitor monitors up to four bits for four muons.
--* An error status register indicates whether any of the bits were
--* set since the status register was last read. Reading the status
--* register clears the error bits.
--* The status register contains in its lowest four bits the error
--* flags of of muon 0, in the next four bits the error flags of muon
--* 1 and so forth.
--*
--* The number of events with an error bit set is separately counted
--* for each bit over the period of an orbit. The counters are
--* automatically cleared at each bc_reset. This means that the value
--* read corresponds to the orbit just before the VME read.
--*
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv2.cern.ch>
--* @version $Revision: 1.1 $
--* @date $Date: 2005/01/10 16:30:16 $x
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use work.VMEMux.all;
use work.IFVMEAddrMap.all;
entity ErrorMonitor4x4bit is
generic (
status_register_address : integer := 0;
counter_register_addresses : TBaseArray(0 to 3));
port (
-- data port
bit0 : in std_logic_vector(0 to 3);
bit1 : in std_logic_vector(0 to 3);
bit2 : in std_logic_vector(0 to 3);
bit3 : in std_logic_vector(0 to 3);
bc_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 ErrorMonitor4x4bit;
-------------------------------------------------------------------------------
-- Implementation
-------------------------------------------------------------------------------
architecture behavioral of ErrorMonitor4x4bit is
signal vme_data_out_i : TVMEData_vec (0 to 16);
signal vme_en_out_i : TVMEEnable_vec (0 to 16);
signal vme_en_out_d : std_logic;
signal vme_en_out_status_pulse : std_logic;
signal error_flags : std_logic_vector(15 downto 0);
begin -- behavioral
-----------------------------------------------------------------------------
--* generate error flags
-----------------------------------------------------------------------------
gen_error_flags: process (clk, reset) is
begin -- process gen_error_flags
if reset = '1' then
error_flags <= ( others => '0');
elsif clk'event and clk = '1' then
if vme_en_out_status_pulse = '1' then
error_flags <= ( others => '0');
else
for imu in 0 to 3 loop
if bit0(imu) = '1' then
error_flags(4*imu) <= '1';
end if;
if bit1(imu) = '1' then
error_flags(4*imu+1) <= '1';
end if;
if bit2(imu) = '1' then
error_flags(4*imu+2) <= '1';
end if;
if bit3(imu) = '1' then
error_flags(4*imu+3) <= '1';
end if;
end loop; -- imu
end if;
end if;
end process gen_error_flags;
-----------------------------------------------------------------------------
--* error flag register
-----------------------------------------------------------------------------
error_flag_reg: entity work.VMEStatusReg
generic map (
my_vme_base_address => status_register_address)
port map (
data => error_flags,
vme_addr => vme_addr,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out_i(16),
vme_en_out => vme_en_out_i(16),
vme_clk => clk,
reset => reset);
-----------------------------------------------------------------------------
--* generate pulse when enable for status register read is cleared
-----------------------------------------------------------------------------
gen_enable_out_pulse: process (clk, reset) is
begin -- process gen_enable_out_pulse
if reset = '1' then
vme_en_out_d <= '0';
vme_en_out_status_pulse <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
vme_en_out_d <= vme_en_out_i(16);
vme_en_out_status_pulse <= vme_en_out_d and not vme_en_out_i(16);
end if;
end process gen_enable_out_pulse;
-----------------------------------------------------------------------------
-- generate error counters
-----------------------------------------------------------------------------
gen_counters: for imu in 0 to 3 generate
begin -- generate gen_counters
error_counter0: entity work.ErrorCounter
generic map (
my_vme_base_address => counter_register_addresses(imu))
port map (
count_enable => bit0(imu),
bc_reset => bc_reset,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(0+4*imu),
vme_en_out => vme_en_out_i(0+4*imu),
clk => clk, reset => reset);
error_counter1: entity work.ErrorCounter
generic map (
my_vme_base_address => counter_register_addresses(imu)+2)
port map (
count_enable => bit1(imu),
bc_reset => bc_reset,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(1+4*imu),
vme_en_out => vme_en_out_i(1+4*imu),
clk => clk, reset => reset);
error_counter2: entity work.ErrorCounter
generic map (
my_vme_base_address => counter_register_addresses(imu)+4)
port map (
count_enable => bit2(imu),
bc_reset => bc_reset,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(2+4*imu),
vme_en_out => vme_en_out_i(2+4*imu),
clk => clk, reset => reset);
error_counter3: entity work.ErrorCounter
generic map (
my_vme_base_address => counter_register_addresses(imu)+6)
port map (
count_enable => bit3(imu),
bc_reset => bc_reset,
vme_addr => vme_addr, vme_en => vme_en, vme_wr => vme_wr,
vme_data_out => vme_data_out_i(3+4*imu),
vme_en_out => vme_en_out_i(3+4*imu),
clk => clk, reset => reset);
end generate gen_counters;
-----------------------------------------------------------------------------
-- multiplex VME outputs
-----------------------------------------------------------------------------
mux_vme(vme_data_out_i, vme_en_out_i, vme_data_out, vme_en_out);
end behavioral;