--******************************************************************************
--* @short 12 bit BX counter used for the read address in the FIFOs of the
--* Input Chips and Sort Chip. Also used as reference bunch counter
--* in the ROP chip.
--*
--* Includes the delay from BCReset to reset of counter. (this delay
--* is the same in all GMT chips).
--* Also generates the L1 accept pulse for either 3 or 5 bx (as
--* configured by VME). In 3bx mode, an extra flip-flop is added to the
--* reset delay so that the delay settign does not have to be
--* changed when switching from 3bx to 5bx mode.
--*
--* The minimum programmable delay (both SRL16 set to 0000) from BCReset
--* to L1A for bunch crossing 0 is 4bx
--* (in 3 bx mode: 2x SRL16 + 1 extra FF + 1 bx read before main bx).
--* (in 5 bx mode: 2x SRL16 + 2 bx read before main bx).
--* The maximum delay between BCReset and L1A for BX 0 (bot SRL set
--* to 1111), is 4+15 = 19 bx.
--******************************************************************************
--* @author SAKULIN Hannes <hsakulin@dsy-srv5.cern.ch>
--* @date $Date: 2004/12/17 09:30:37 $
--* @version $Revision: 1.3 $
--******************************************************************************
--/
library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_std.all;
-- pragma translate_off
library UNISIM;
use UNISIM.VCOMPONENTS.all;
-- pragma translate_on
entity BXReadCounter is
generic (
lat_delay_reg_addr : integer); -- address of LATENCY delay register
port (
iBCReset : in std_logic; -- bcreset after input FF and decoding
iL1A : in std_logic; -- L1A after input FF and decoding
oDo5BX : out std_logic;
oBXReadCounter : out std_logic_vector(11 downto 0);
oL1A_pulse : out std_logic;
-- VME port (for latency delay register)
vme_addr : in std_logic_vector;
vme_data : in std_logic_vector;
vme_en : in std_logic;
vme_wr : in std_logic;
vme_data_out : out std_logic_vector(15 downto 0);
vme_en_out : out std_logic;
-- Clock, control
clk : in std_logic;
reset : in std_logic -- asynch reset
);
end entity BXReadCounter;
architecture behavioral of BXReadCounter is
component SRL16
-- synthesis translate_off
generic (
INIT: bit_vector:= X"0001");
-- synthesis translate_on
port (Q : out STD_ULOGIC;
A0 : in STD_ULOGIC;
A1 : in STD_ULOGIC;
A2 : in STD_ULOGIC;
A3 : in STD_ULOGIC;
CLK : in STD_ULOGIC;
D : in STD_ULOGIC);
end component;
signal sLAT_DelayReg : std_logic_vector(15 downto 0);
signal bcres_delayed : std_logic;
signal bcres_srl1 : std_logic;
signal bcres_srl2 : std_logic;
signal bcres_srl2_d : std_logic;
signal sDo5BX : std_logic;
signal sL1A_d1 : std_logic;
signal sL1A_d2 : std_logic;
signal sL1A_d3 : std_logic;
signal sL1A_d4 : std_logic;
begin -- architecture behavioral
-----------------------------------------------------------------------------
-- Configuration Register
-----------------------------------------------------------------------------
--
-- 0 0 0 0 | 0 0 0 0 | 0 0 0 0 | 0 0 0 0
-- | | | | | LAT delay2 | LAT delay1
-- |
-- |
-- +================ do five BX readout (1) / do three BX readout (0)
--
--
readout_sync_reg: entity work.VMEReg
generic map (
-- *** change the default here, to simulate different latencies or to
-- switch from 3bx mode to 5bx mode ***
init_val => "0000000000001000",
my_vme_base_address => lat_delay_reg_addr )
port map (
data => sLAT_DelayReg,
reset => reset,
vme_addr => vme_addr,
vme_data => vme_data,
vme_en => vme_en,
vme_wr => vme_wr,
vme_data_out => vme_data_out,
vme_en_out => vme_en_out,
vme_clk => clk);
sDo5BX <= sLAT_DelayReg(15);
oDo5BX <= sDo5BX;
-----------------------------------------------------------------------------
-- BCReset delay for ROP read counter = LATENCY
-----------------------------------------------------------------------------
bcres_lat_delay1_block: SRL16
port map (
D => iBCReset,
Q => bcres_srl1,
A0 => sLAT_DelayReg(0),
A1 => sLAT_DelayReg(1),
A2 => sLAT_DelayReg(2),
A3 => sLAT_DelayReg(3),
CLK => clk);
bcres_lat_delay2_block: SRL16
port map (
D => bcres_srl1,
Q => bcres_srl2,
A0 => sLAT_DelayReg(4),
A1 => sLAT_DelayReg(5),
A2 => sLAT_DelayReg(6),
A3 => sLAT_DelayReg(7),
CLK => clk);
delay_more: process (clk, reset) is
begin -- process delay_more
if reset = '1' then
bcres_srl2_d <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
bcres_srl2_d <= bcres_srl2;
end if;
end process delay_more;
-- need to start read counter 1 bx later in 5bx mode.
-- it then starts reading data one bx lower.
bcres_delayed <= bcres_srl2_d when sDo5BX = '1' else bcres_srl2;
-----------------------------------------------------------------------------
-- BX read (or reference) counter
-----------------------------------------------------------------------------
bx_counter: process (clk, reset) is
variable counter : std_logic_vector(11 downto 0) := "000000000000";
begin
if reset = '1' then
counter := "000000000000";
oBXReadCounter <= "000000000000";
elsif clk'event and clk = '1' then
if bcres_delayed = '1' then
counter := "000000000000";
else
counter := std_logic_vector(TO_UNSIGNED(TO_INTEGER(UNSIGNED(counter))+1,12));
end if;
end if;
oBXReadCounter <= counter;
end process bx_counter;
-----------------------------------------------------------------------------
-- make l1 pulse for 3 (5) bx
-----------------------------------------------------------------------------
delay_l1a: process (clk, reset) is
begin -- process delay_l1a
if reset = '1' then
sL1A_d1 <= '0';
sL1A_d2 <= '0';
sL1A_d3 <= '0';
sL1A_d4 <= '0';
elsif clk'event and clk = '1' then -- rising clock edge
sL1A_d1 <= iL1A;
sL1A_d2 <= sL1A_d1;
sL1A_d3 <= sL1A_d2;
sL1A_d4 <= sL1A_d3;
end if;
end process delay_l1a;
oL1A_pulse <= iL1A or sL1A_d1 or sL1A_d2 or ( ( sL1A_d3 or sL1A_d4) and sDo5BX );
end architecture behavioral;