------------------------------------------------------------------------------- -- Title : pt reconstruction unit -- Project : Prototype implementation of the GTU of the Alice TRD Experiment ------------------------------------------------------------------------------- -- File : reconst.vhd -- Author : Jan de Cuveland -- Company : -- Last update: 2004/04/28 -- Platform : ------------------------------------------------------------------------------- -- This is a prototype implementation of the Global Tracking Unit (GTU) -- of the Alice TRD detector. ------------------------------------------------------------------------------- -- Description: ------------------------------------------------------------------------------- -- Revisions : -- Date Version Author Description -- 2003/07/01 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 reconst is port ( clk : in std_logic; rst_n : in std_logic; valid_in : in std_logic; ready_in : in std_logic; track_in : in std_logic_vector(track_width-1 downto 0); valid_out : out std_logic; ready_out : out std_logic; track_out : out std_logic_vector(track_width-1 downto 0); pt_out : out signed(pt_width-1 downto 0); mem5_addr : out unsigned(addr_width-1 downto 0); mem4_addr : out unsigned(addr_width-1 downto 0); mem3_addr : out unsigned(addr_width-1 downto 0); mem2_addr : out unsigned(addr_width-1 downto 0); mem1_addr : out unsigned(addr_width-1 downto 0); mem0_addr : out unsigned(addr_width-1 downto 0); mem5_ys : in signed(ypos_width-1 downto 0); mem4_ys : in signed(ypos_width-1 downto 0); mem3_ys : in signed(ypos_width-1 downto 0); mem2_ys : in signed(ypos_width-1 downto 0); mem1_ys : in signed(ypos_width-1 downto 0); mem0_ys : in signed(ypos_width-1 downto 0); mem5_pid : in std_logic_vector(pid_width-1 downto 0); mem4_pid : in std_logic_vector(pid_width-1 downto 0); mem3_pid : in std_logic_vector(pid_width-1 downto 0); mem2_pid : in std_logic_vector(pid_width-1 downto 0); mem1_pid : in std_logic_vector(pid_width-1 downto 0); mem0_pid : in std_logic_vector(pid_width-1 downto 0)); end; ------------------------------------------------------------------------------- architecture default of reconst is -- constant div_stages : integer := 11; -- number of divider pipeline stages constant div_stages : integer := 7; -- must be '7' for xilinx module -- constant div_stages : integer := 0; -- number of divider pipeline stages signal rst : std_logic; -- pipeline register signals type pid_t6 is array (5 downto 0) of std_logic_vector(pid_width-1 downto 0); type ypos_t6 is array (5 downto 0) of signed(ypos_width-1 downto 0); type acoeff_t6 is array (5 downto 0) of signed(12 downto 0); type ai_t6 is array (5 downto 0) of signed(17 downto 0); -- stage 0: signal valid_stage0 : std_logic; signal ready_stage0 : std_logic; signal track_stage0 : std_logic_vector(track_width-1 downto 0); -- stage 1a: signal valid_stage1a : std_logic; signal ready_stage1a : std_logic; signal track_stage1a : std_logic_vector(track_width-1 downto 0); signal pid_stage1a : pid_t6; signal ys_stage1a : ypos_t6; signal acoeff_stage1a : acoeff_t6; signal mask_id_stage1a : unsigned(4 downto 0); -- stage 1b: signal valid_stage1b : std_logic; signal ready_stage1b : std_logic; signal track_stage1b : std_logic_vector(track_width-1 downto 0); signal mask_id_stage1b : unsigned(4 downto 0); -- stage 2: signal valid_stage2 : std_logic; signal ready_stage2 : std_logic; signal track_stage2 : std_logic_vector(track_width-1 downto 0); signal ai_stage2 : ai_t6; signal mask_id_stage2 : unsigned(4 downto 0); -- stage 3: signal valid_stage3 : std_logic; signal ready_stage3 : std_logic; signal track_stage3 : std_logic_vector(track_width-1 downto 0); signal a_stage3 : signed(15 downto 0); signal c1_stage3 : signed(12 downto 0); -- stage 4: signal valid_stage4 : std_logic; signal ready_stage4 : std_logic; signal track_stage4 : std_logic_vector(track_width-1 downto 0); signal pt_raw_stage4 : signed(20 downto 0); -- stage 0: signal mask_comb0 : std_logic_vector(5 downto 0); signal mask_id_comb0 : unsigned(4 downto 0); signal acoeff_comb0 : acoeff_t6; -- stage 1b: signal ai_comb1b : ai_t6; -- stage 2: signal a_full_comb2 : signed(17 downto 0); signal a_ext_comb2 : signed(17 downto 0); signal c1_comb2 : signed(12 downto 0); -- stage 3: signal c1_ext_comb3 : signed(20 downto 0); signal pt_raw_comb3 : signed(20 downto 0); -- stage 4: signal pt_raw_comb4 : signed(16 downto 0); signal pt_ext_comb4 : signed(16 downto 0); -- delay shift registers type track_tn is array (div_stages downto 0) of std_logic_vector(track_width-1 downto 0); signal valid_sreg : std_logic_vector(div_stages downto 0); signal ready_sreg : std_logic_vector(div_stages downto 0); signal track_sreg : track_tn; begin rst <= not rst_n; -- connect look-up tables mask_id_lut_inst : entity work.mask_id_lut port map ( mask => mask_comb0, mask_id => mask_id_comb0); lgen : for plane in 5 downto 0 generate acoeff_lut_inst : entity work.acoeff_lut generic map ( plane => plane) port map ( mask_id => mask_id_comb0, acoeff => acoeff_comb0(plane)); end generate; c1_lut_inst : entity work.c1_lut port map ( mask_id => mask_id_stage2, c1 => c1_comb2); -- connect combinatorial logic -- stage 0: mask_comb0 <= track_stage0(matchvec_high downto matchvec_low); -- stage 1b: cgen : for plane in 5 downto 0 generate mult_wrapper_inst : entity work.mult_wrapper port map ( a => acoeff_stage1a(plane), b => ys_stage1a(plane), aclr => rst, clk => clk, result => ai_comb1b(plane)); end generate; -- stage 2: a_full_comb2 <= ai_stage2(0) + ai_stage2(1) + ai_stage2(2) + ai_stage2(3) + ai_stage2(4) + ai_stage2(5); a_ext_comb2 <= a_full_comb2 + 3 when a_full_comb2(a_full_comb2'high) = '1' else a_full_comb2; -- stage 3: c1_ext_comb3 <= c1_stage3 & "00000000"; -- stage 4: pt_raw_comb4 <= pt_raw_stage4(pt_raw_stage4'high-4 downto 0); pt_ext_comb4 <= pt_raw_comb4 - 29 when pt_raw_comb4(pt_raw_comb4'high) = '1' else pt_raw_comb4 + 32; -- final divider divide_wrapper_inst : entity work.divide_wrapper generic map ( div_stages => div_stages) port map ( numer => c1_ext_comb3, denom => a_stage3, aclr => rst, clk => clk, quotient => pt_raw_comb3); -- registers with asynchronous reset process (clk, rst_n) begin if rst_n = '0' then -- stage 0: valid_stage0 <= '0'; ready_stage0 <= '0'; -- stage 1a: valid_stage1a <= '0'; ready_stage1a <= '0'; -- stage 1b: valid_stage1b <= '0'; ready_stage1b <= '0'; -- stage 2: valid_stage2 <= '0'; ready_stage2 <= '0'; -- stage 3: valid_stage3 <= '0'; ready_stage3 <= '0'; -- stage 4: valid_stage4 <= '0'; ready_stage4 <= '0'; elsif clk'event and clk = '1' then -- stage 0: valid_stage0 <= valid_in; ready_stage0 <= ready_in; -- stage 1a: valid_stage1a <= valid_stage0; ready_stage1a <= ready_stage0; -- stage 1b: valid_stage1b <= valid_stage1a; ready_stage1b <= ready_stage1a; -- stage 2: valid_stage2 <= valid_stage1b; ready_stage2 <= ready_stage1b; -- stage 3: valid_stage3 <= valid_stage2; ready_stage3 <= ready_stage2; -- stage 4: valid_stage4 <= valid_stage3; ready_stage4 <= ready_stage3; end if; end process; -- registers without reset process (clk, rst_n) begin if clk'event and clk = '1' then -- stage 0: track_stage0 <= track_in; -- stage 1a: track_stage1a <= track_stage0; pid_stage1a(5) <= mem5_pid; pid_stage1a(4) <= mem4_pid; pid_stage1a(3) <= mem3_pid; pid_stage1a(2) <= mem2_pid; pid_stage1a(1) <= mem1_pid; pid_stage1a(0) <= mem0_pid; ys_stage1a(5) <= mem5_ys; ys_stage1a(4) <= mem4_ys; ys_stage1a(3) <= mem3_ys; ys_stage1a(2) <= mem2_ys; ys_stage1a(1) <= mem1_ys; ys_stage1a(0) <= mem0_ys; acoeff_stage1a <= acoeff_comb0; mask_id_stage1a <= mask_id_comb0; -- stage 1b: track_stage1b <= track_stage1a; mask_id_stage1b <= mask_id_stage1a; -- stage 2: track_stage2 <= track_stage1b; ai_stage2 <= ai_comb1b; mask_id_stage2 <= mask_id_stage1b; -- stage 3: track_stage3 <= track_stage2; a_stage3 <= a_ext_comb2(a_ext_comb2'high downto 2); c1_stage3 <= c1_comb2; -- stage 4: track_stage4 <= track_stage3; pt_raw_stage4 <= pt_raw_comb3; end if; end process; -- delay shift registers valid_sreg(0) <= valid_stage4; ready_sreg(0) <= ready_stage4; track_sreg(0) <= track_stage4; sreg_gen : for i in div_stages downto 1 generate process (clk, rst_n) begin if rst_n = '0' then valid_sreg(i) <= '0'; ready_sreg(i) <= '0'; elsif clk'event and clk = '1' then valid_sreg(i) <= valid_sreg(i - 1); ready_sreg(i) <= ready_sreg(i - 1); end if; end process; process (clk) begin if clk'event and clk = '1' then track_sreg(i) <= track_sreg(i - 1); end if; end process; end generate sreg_gen; -- connect output signals valid_out <= valid_sreg(div_stages); ready_out <= ready_sreg(div_stages); track_out <= track_sreg(div_stages); pt_out <= pt_ext_comb4(pt_ext_comb4'high downto 1); mem5_addr <= unsigned(track_stage0(addr0_high + 5 * addr_width downto addr0_low + 5 * addr_width)); mem4_addr <= unsigned(track_stage0(addr0_high + 4 * addr_width downto addr0_low + 4 * addr_width)); mem3_addr <= unsigned(track_stage0(addr0_high + 3 * addr_width downto addr0_low + 3 * addr_width)); mem2_addr <= unsigned(track_stage0(addr0_high + 2 * addr_width downto addr0_low + 2 * addr_width)); mem1_addr <= unsigned(track_stage0(addr0_high + 1 * addr_width downto addr0_low + 1 * addr_width)); mem0_addr <= unsigned(track_stage0(addr0_high + 0 * addr_width downto addr0_low + 0 * addr_width)); end;