------------------------------------------------------------------------------- -- Title : Combinatorial Matching Logic -- Project : Prototype implementation of the GTU of the Alice TRD Experiment ------------------------------------------------------------------------------- -- File : matching_logic.vhd -- Author : Jan de Cuveland -- Company : -- Last update: 2003/06/03 -- Platform : ------------------------------------------------------------------------------- -- This is a prototype implementation of the Global Tracking Unit (GTU) -- of the Alice TRD detector. ------------------------------------------------------------------------------- -- Description: ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2003/02/18 1.0 cuveland Created ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use work.gtu_types.all; ------------------------------------------------------------------------------- entity matching_logic is generic ( seedline : integer; line_mask : integer); port ( i5a, i5b : in unsigned(2 downto 0); i4a, i4b : in unsigned(2 downto 0); i3a, i3b : in unsigned(2 downto 0); i2a, i2b : in unsigned(2 downto 0); i1a, i1b : in unsigned(2 downto 0); i0a, i0b : in unsigned(2 downto 0); y5a, y5b : in signed(proj_ypos_width-1 downto 0); y4a, y4b : in signed(proj_ypos_width-1 downto 0); y3a, y3b : in signed(proj_ypos_width-1 downto 0); y2a, y2b : in signed(proj_ypos_width-1 downto 0); y1a, y1b : in signed(proj_ypos_width-1 downto 0); y0a, y0b : in signed(proj_ypos_width-1 downto 0); a5a, a5b : in signed(deflang_width-1 downto 0); a4a, a4b : in signed(deflang_width-1 downto 0); a3a, a3b : in signed(deflang_width-1 downto 0); a2a, a2b : in signed(deflang_width-1 downto 0); a1a, a1b : in signed(deflang_width-1 downto 0); a0a, a0b : in signed(deflang_width-1 downto 0); inc5 : out unsigned(1 downto 0); inc4 : out unsigned(1 downto 0); inc3 : out unsigned(1 downto 0); inc2 : out unsigned(1 downto 0); inc1 : out unsigned(1 downto 0); inc0 : out unsigned(1 downto 0); match : out std_logic; matchvec : out std_logic_vector(5 downto 0); ab_select : out std_logic_vector(5 downto 0)); end matching_logic; ------------------------------------------------------------------------------- architecture default of matching_logic is type incvec_t is array (5 downto 0) of unsigned(1 downto 0); signal inc : incvec_t; signal tinc : incvec_t; type ii_t is array (5 downto 0) of unsigned(2 downto 0); signal ia, ib : ii_t; type yi_t is array (5 downto 0) of signed(proj_ypos_width-1 downto 0); signal ya, yb : yi_t; type ai_t is array (5 downto 0) of signed(deflang_width-1 downto 0); signal aa, ab : ai_t; constant delta_y : signed(proj_ypos_width-1 downto 0) := proj_ypos_window; constant delta_a : signed(deflang_width-1 downto 0) := deflang_window; constant mask : std_logic_vector(5 downto 0) := conv_std_logic_vector(line_mask, 6); signal ysa_plus : signed(proj_ypos_width-1 downto 0); signal ysa_minus : signed(proj_ypos_width-1 downto 0); signal ysb_plus : signed(proj_ypos_width-1 downto 0); signal ysb_minus : signed(proj_ypos_width-1 downto 0); signal asa_plus : signed(deflang_width-1 downto 0); signal asa_minus : signed(deflang_width-1 downto 0); signal cmp_a_ll_a : std_logic_vector(5 downto 0); signal cmp_a_gg_a : std_logic_vector(5 downto 0); signal cmp_a_ll_b : std_logic_vector(5 downto 0); signal cmp_a_gg_b : std_logic_vector(5 downto 0); signal cmp_b_ll_a : std_logic_vector(5 downto 0); signal cmp_b_gg_a : std_logic_vector(5 downto 0); signal cmp_b_ll_b : std_logic_vector(5 downto 0); signal ang_a_ll_a : std_logic_vector(5 downto 0); signal ang_a_gg_a : std_logic_vector(5 downto 0); signal ang_b_ll_a : std_logic_vector(5 downto 0); signal ang_b_gg_a : std_logic_vector(5 downto 0); signal is_aligned : std_logic_vector(5 downto 0); signal a_matches : std_logic_vector(5 downto 0); signal b_matches : std_logic_vector(5 downto 0); signal has_match : std_logic_vector(5 downto 0); signal is_far_beyond : std_logic_vector(5 downto 0); signal num_match : unsigned(2 downto 0); signal num_not_aligned : unsigned(2 downto 0); signal num_far_beyond : unsigned(2 downto 0); signal num_possible_match : unsigned(2 downto 0); begin -- default arith : process (ya, yb, aa) begin -- process arith ysa_plus <= ya(seedline) + delta_y; ysa_minus <= ya(seedline) - delta_y; ysb_plus <= yb(seedline) + delta_y; ysb_minus <= yb(seedline) - delta_y; asa_plus <= aa(seedline) + delta_a; asa_minus <= aa(seedline) - delta_a; end process arith; gen6 : for i in 5 downto 0 generate seed_line : if i = seedline generate cmp_a_ll_a(i) <= '0'; cmp_a_gg_a(i) <= '0'; cmp_a_ll_b(i) <= '0'; cmp_a_gg_b(i) <= '0'; cmp_b_ll_a(i) <= '1'; cmp_b_gg_a(i) <= '0'; cmp_b_ll_b(i) <= '0'; ang_a_ll_a(i) <= '0'; ang_a_gg_a(i) <= '0'; ang_b_ll_a(i) <= '0'; ang_b_gg_a(i) <= '0'; end generate seed_line; other_line : if i /= seedline generate cmp_a_ll_a(i) <= '1' when (ia(i) < ia(seedline)) or ((ia(i) = ia(seedline)) and (ya(i) < ysa_minus)) else '0'; cmp_a_gg_a(i) <= '1' when (ia(i) > ia(seedline)) or ((ia(i) = ia(seedline)) and (ya(i) > ysa_plus)) else '0'; cmp_a_ll_b(i) <= '1' when (ia(i) < ib(seedline)) or ((ia(i) = ib(seedline)) and (ya(i) < ysb_minus)) else '0'; cmp_a_gg_b(i) <= '1' when (ia(i) > ib(seedline)) or ((ia(i) = ib(seedline)) and (ya(i) > ysb_plus)) else '0'; cmp_b_ll_a(i) <= '1' when (ib(i) < ia(seedline)) or ((ib(i) = ia(seedline)) and (yb(i) < ysa_minus)) else '0'; cmp_b_gg_a(i) <= '1' when (ib(i) > ia(seedline)) or ((ib(i) = ia(seedline)) and (yb(i) > ysa_plus)) else '0'; cmp_b_ll_b(i) <= '1' when (ib(i) < ib(seedline)) or ((ib(i) = ib(seedline)) and (yb(i) < ysb_minus)) else '0'; ang_a_ll_a(i) <= '1' when aa(i) < asa_minus else '0'; ang_a_gg_a(i) <= '1' when aa(i) > asa_plus else '0'; ang_b_ll_a(i) <= '1' when ab(i) < asa_minus else '0'; ang_b_gg_a(i) <= '1' when ab(i) > asa_plus else '0'; end generate other_line; is_aligned(i) <= not cmp_a_ll_a(i); a_matches(i) <= not cmp_a_ll_a(i) and not cmp_a_gg_a(i) and not ang_a_ll_a(i) and not ang_a_gg_a(i); b_matches(i) <= not cmp_b_ll_a(i) and not cmp_b_gg_a(i) and not ang_b_ll_a(i) and not ang_b_gg_a(i); has_match(i) <= is_aligned(i) and (a_matches(i) or b_matches(i)); is_far_beyond(i) <= cmp_a_gg_b(i); end generate gen6; sum_match : process (has_match) variable sum : unsigned(2 downto 0); begin -- process sum_match sum := "000"; for i in has_match'range loop if has_match(i) = '1' then sum := sum + "001"; end if; end loop; -- i num_match <= sum; end process sum_match; sum_not_aligned : process (is_aligned) variable sum : unsigned(2 downto 0); begin -- process sum_not_aligned sum := "000"; for i in is_aligned'range loop if is_aligned(i) = '0' then sum := sum + "001"; end if; end loop; -- i num_not_aligned <= sum; end process sum_not_aligned; sum_far_beyond : process (is_far_beyond) variable sum : unsigned(2 downto 0); begin -- process sum_far_beyond sum := "000"; for i in is_far_beyond'range loop if is_far_beyond(i) = '1' then sum := sum + "001"; end if; end loop; -- i num_far_beyond <= sum; end process sum_far_beyond; num_possible_match <= num_not_aligned + num_match; match <= '1' when (num_match(2) = '1') and ((has_match and mask) = "000000") and is_aligned = "111111" else '0'; adv6 : for i in 5 downto 0 generate seed_line : if i = seedline generate inc_gen : process (num_not_aligned, num_possible_match, num_far_beyond) begin -- process inc_gen if (num_not_aligned /= unsigned'("000")) and (num_possible_match(2) = '1') then inc(seedline) <= "00"; elsif num_far_beyond >= conv_unsigned(3, 3) then inc(seedline) <= "10"; else inc(seedline) <= "01"; end if; end process inc_gen; tinc(seedline) <= "00"; end generate seed_line; other_line : if i /= seedline generate tinc_gen : process (cmp_b_ll_b, cmp_a_ll_b) begin -- process tinc_gen if cmp_b_ll_b(i) = '1' then tinc(i) <= "10"; elsif cmp_a_ll_b(i) = '1' then tinc(i) <= "01"; else tinc(i) <= "00"; end if; end process tinc_gen; inc_gen : process (inc, tinc, cmp_a_ll_a, cmp_a_gg_a, cmp_b_ll_a, cmp_b_gg_a) begin -- process inc_gen if inc(seedline) /= 0 then inc(i) <= tinc(i); else if not cmp_a_ll_a(i) = '1' and not cmp_a_gg_a(i) = '1' then inc(i) <= "00"; elsif cmp_b_ll_a(i) = '1' then inc(i) <= "10"; elsif not cmp_b_gg_a(i) = '1' then inc(i) <= "01"; else inc(i) <= tinc(i); end if; end if; end process inc_gen; end generate other_line; end generate adv6; sel6 : for i in 5 downto 0 generate seed_line : if i = seedline generate ab_select(i) <= '0'; -- always select 'a' for seed line end generate seed_line; other_line : if i /= seedline generate ab_select(i) <= not a_matches(i); -- select first fit -- for best fit: additional comparisons would be neccessary end generate other_line; end generate sel6; matchvec <= has_match; ia(5) <= i5a; ia(4) <= i4a; ia(3) <= i3a; ia(2) <= i2a; ia(1) <= i1a; ia(0) <= i0a; ib(5) <= i5b; ib(4) <= i4b; ib(3) <= i3b; ib(2) <= i2b; ib(1) <= i1b; ib(0) <= i0b; ya(5) <= y5a; ya(4) <= y4a; ya(3) <= y3a; ya(2) <= y2a; ya(1) <= y1a; ya(0) <= y0a; yb(5) <= y5b; yb(4) <= y4b; yb(3) <= y3b; yb(2) <= y2b; yb(1) <= y1b; yb(0) <= y0b; aa(5) <= a5a; aa(4) <= a4a; aa(3) <= a3a; aa(2) <= a2a; aa(1) <= a1a; aa(0) <= a0a; ab(5) <= a5b; ab(4) <= a4b; ab(3) <= a3b; ab(2) <= a2b; ab(1) <= a1b; ab(0) <= a0b; inc5 <= inc(5); inc4 <= inc(4); inc3 <= inc(3); inc2 <= inc(2); inc1 <= inc(1); inc0 <= inc(0); end default;