------------------------------------------------------------------------------- -- Title : Buffer / Merger -- Project : Prototype implementation of the GTU of the Alice TRD Experiment ------------------------------------------------------------------------------- -- File : buffer_merger.vhd -- Author : Jan de Cuveland -- Company : -- Last update: 2004/04/27 -- Platform : ------------------------------------------------------------------------------- -- This is a prototype implementation of the Global Tracking Unit (GTU) -- of the Alice TRD detector. ------------------------------------------------------------------------------- -- Description: ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2003/03/11 1.0 cuveland Created ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.gtu_types.all; ------------------------------------------------------------------------------- entity buffer_merger is port ( clk : in std_logic; rst_n : in std_logic; pretrigger : in std_logic; -- Link 1 clk1_in : in std_logic; valid1_in : in std_logic; data1_in : in std_logic_vector(31 downto 0); -- Link 0 clk0_in : in std_logic; valid0_in : in std_logic; data0_in : in std_logic_vector(31 downto 0); -- Outputs y_out : out signed(ypos_width-1 downto 0); d_out : out signed(deflen_width-1 downto 0); z_out : out unsigned(zpos_width-1 downto 0); pid_out : out std_logic_vector(pid_width-1 downto 0); end_out : out std_logic; valid_out : out std_logic ); end buffer_merger; ------------------------------------------------------------------------------- architecture default of buffer_merger is constant const_1 : std_logic := '1'; signal aclr : std_logic; type data_t is array (1 downto 0) of std_logic_vector(31 downto 0); -- input signals signal data_in : data_t; signal clk_in : std_logic_vector(1 downto 0); signal valid_in : std_logic_vector(1 downto 0); -- internal signals signal data : data_t; signal data_out : std_logic_vector(31 downto 0); signal empty : std_logic_vector(1 downto 0); signal rdreq : std_logic_vector(1 downto 0); signal pop : std_logic_vector(1 downto 0); signal data_is_end_word : std_logic_vector(1 downto 0); -- registers type state_t is (idle, running); signal state, next_state : state_t; signal valid, next_valid : std_logic_vector(1 downto 0); begin y_out <= signed(data_out(ypos_offset+ypos_width-1 downto ypos_offset)); d_out <= signed(data_out(deflen_offset+deflen_width-1 downto deflen_offset)); z_out <= unsigned(data_out(zpos_offset+zpos_width-1 downto zpos_offset)); pid_out <= data_out(pid_offset+pid_width-1 downto pid_offset); aclr <= not rst_n or pretrigger; -- input signals data_in(1) <= data1_in; data_in(0) <= data0_in; valid_in(1) <= valid1_in; valid_in(0) <= valid0_in; clk_in(1) <= clk1_in; clk_in(0) <= clk0_in; gen : for i in 1 downto 0 generate fifo_dc_wrapper_inst : entity work.fifo_dc_wrapper port map ( data => data_in(i), wrclk => clk_in(i), rdclk => clk, wrreq => valid_in(i), rdreq => rdreq(i), aclr => aclr, rdempty => empty(i), q => data(i)); data_is_end_word(i) <= '1' when is_end_word(data(i)) else '0'; process (valid, pop, empty) begin if valid(i) = '0' or pop(i) = '1' then if empty(i) = '0' then rdreq(i) <= '1'; next_valid(i) <= '1'; else rdreq(i) <= '0'; next_valid(i) <= '0'; end if; else rdreq(i) <= '0'; next_valid(i) <= '1'; end if; end process; end generate gen; -- registers process (clk, rst_n) begin if rst_n = '0' then state <= idle; valid <= "00"; elsif rising_edge(clk) then state <= next_state; valid <= next_valid; end if; end process; process (state, pretrigger, valid, data, data_is_end_word) begin pop <= "00"; data_out <= (data_out'range => '0'); end_out <= '0'; valid_out <= '0'; next_state <= running; if state = idle then if pretrigger = '0' then next_state <= idle; end if; else -- state = running if valid = "11" then valid_out <= '1'; if data_is_end_word(1) = '1' then data_out <= data(0); end_out <= data_is_end_word(0); if data_is_end_word(0) = '1' then pop <= "11"; next_state <= idle; else pop <= "01"; end if; else if data_is_end_word(0) = '1' or data(1)(zpos_offset+zpos_width-1 downto zpos_offset) < data(0)(zpos_offset+zpos_width-1 downto zpos_offset) then data_out <= data(1); end_out <= data_is_end_word(1); pop <= "10"; else data_out <= data(0); end_out <= data_is_end_word(0); pop <= "01"; end if; end if; end if; end if; end process; end default;