------------------------------------------------------------------------------- -- Title : Serial track uniquifier -- Project : Prototype implementation of the GTU of the Alice TRD Experiment ------------------------------------------------------------------------------- -- File : uniquify.vhd -- Author : Jan de Cuveland -- Company : -- Last update: 2004/04/29 -- Platform : ------------------------------------------------------------------------------- -- This is a prototype implementation of the Global Tracking Unit (GTU) -- of the Alice TRD detector. ------------------------------------------------------------------------------- -- Description: ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2003/06/16 1.0 cuveland Created ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.gtu_types.all; use work.track_types.all; ------------------------------------------------------------------------------- entity uniquifier is generic ( width : integer); port ( clk : in std_logic; rst_n : in std_logic; track_in : in std_logic_vector(width-1 downto 0); valid_in : in std_logic; ready_in : in std_logic; track_out : out std_logic_vector(width-1 downto 0); valid_out : out std_logic; ready_out : out std_logic); end uniquifier; ------------------------------------------------------------------------------- architecture default of uniquifier is -- uniquifier registers signal data_stage0 : std_logic_vector(width-1 downto 0); signal data_stage1 : std_logic_vector(width-1 downto 0); signal ready_stage0 : std_logic; signal valid_stage0 : std_logic; signal valid_stage1 : std_logic; -- uniquifier control signals signal data_stage1_enable : std_logic; signal next_valid_stage1 : std_logic; signal drop : std_logic_vector(1 downto 0); signal equals : std_logic_vector(5 downto 0); function count_bits ( signal a : std_logic_vector) return integer is variable sum : integer := 0; begin for i in a'range loop if a(i) = '1' then sum := sum + 1; end if; end loop; return sum; end; begin -- uniquifier registers (with reset) process (clk, rst_n) begin if rst_n = '0' then -- stage0 valid_stage0 <= '0'; -- stage1 valid_stage1 <= '0'; elsif clk'event and clk = '1' then -- stage0 valid_stage0 <= valid_in; -- stage1 valid_stage1 <= next_valid_stage1; end if; end process; -- uniquifier registers (without reset) process (clk) begin if clk'event and clk = '1' then -- stage0 data_stage0 <= track_in; ready_stage0 <= ready_in; -- stage1 if data_stage1_enable = '1' then data_stage1 <= data_stage0; end if; end if; end process; track_out <= data_stage1; -- uniquifier control logic process (ready_stage0, valid_stage0, valid_stage1, drop) variable output : std_logic_vector(3 downto 0); variable input : std_logic_vector(2 downto 0); begin input := ready_stage0 & valid_stage0 & valid_stage1; output := "0000"; case input is when "000" => output := "0000"; when "001" => output := "0100"; when "010" => output := "1100"; when "011" => case drop is when "10" => output := "1100"; when "01" => output := "0100"; when "00" => output := "1110"; when others => null; end case; when "100" => output := "0001"; when "101" => output := "0010"; when "110" => output := "1100"; when "111" => case drop is when "10" => output := "1100"; when "01" => output := "0010"; when "00" => output := "1110"; when others => null; end case; when others => null; end case; data_stage1_enable <= output(3); next_valid_stage1 <= output(2); valid_out <= output(1); ready_out <= output(0); end process; -- uniquifier compare logic gen6 : for i in 5 downto 0 generate equals(i) <= '1' when data_stage0(matchvec_low + i) = '1' and data_stage1(matchvec_low + i) = '1' and data_stage0(addr0_high + i * addr_width downto addr0_low + i * addr_width) = data_stage1(addr0_high + i * addr_width downto addr0_low + i * addr_width) else '0'; end generate gen6; process (equals, data_stage0, data_stage1) begin drop <= "00"; if equals /= "000000" then if count_bits(data_stage0(matchvec_high downto matchvec_low)) >= count_bits(data_stage1(matchvec_high downto matchvec_low)) then drop <= "10"; else drop <= "01"; end if; end if; end process; end default;