From 0215724ec9c43bf8a76c860dda3392a3e89a9f15 Mon Sep 17 00:00:00 2001 From: Jan Michel Date: Wed, 25 May 2016 11:15:36 +0200 Subject: [PATCH] Multi-channel TDC (one channel read- out at a time) --- code/ffarray.vhd | 129 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/code/ffarray.vhd b/code/ffarray.vhd index 52bd3ee..ea21aed 100644 --- a/code/ffarray.vhd +++ b/code/ffarray.vhd @@ -7,12 +7,16 @@ use work.trb_net_std.all; entity ffarray is + generic( + CHANNELS : integer := 1 + ); port( CLK : in std_logic; RESET_IN : in std_logic; - SIGNAL_IN : in std_logic; + SIGNAL_IN : in std_logic_vector(CHANNELS-1 downto 0); - DATA_OUT : out std_logic_vector(8 downto 0); + SELECT_IN : in std_logic_vector(3 downto 0); + DATA_OUT : out std_logic_vector(31 downto 0); READ_IN : in std_logic := '0'; EMPTY_OUT : out std_logic := '0' ); @@ -26,17 +30,25 @@ attribute syn_hier of ffarray_arch : architecture is "hard"; signal CLKt : std_logic_vector(3 downto 0); signal CLKa : std_logic_vector(7 downto 0); -signal final1, final2 : std_logic_vector(7 downto 0); -signal final_t : std_logic_vector(7 downto 0); -signal final : std_logic_vector(8 downto 0); -type ffarr_t is array(0 to 3) of std_logic_vector(7 downto 0); +type vector_arr_5 is array (0 to CHANNELS-1) of std_logic_vector(5 downto 0); +type vector_arr_8 is array (0 to CHANNELS-1) of std_logic_vector(7 downto 0); +type vector_arr_9 is array (0 to CHANNELS-1) of std_logic_vector(9 downto 0); + +signal final1, final2 : vector_arr_8; +signal final_t : vector_arr_8; +signal final : vector_arr_9; +type ffarr_t is array(0 to 2) of vector_arr_8; signal ffarr : ffarr_t; +signal finalval : vector_arr_5; type ram_t is array(0 to 1023) of std_logic_vector(7 downto 0); signal ram : ram_t; -signal fifo_write, last : std_logic; +signal fifo_write, last, fifo_write_val : std_logic_vector(CHANNELS-1 downto 0); +signal fifo_real_write, fifo_empty, valid_read : std_logic; +signal fifo_data : std_logic_vector(35 downto 0); +signal fifo_data_out : std_logic_vector(35 downto 0); attribute syn_preserve : boolean; attribute syn_keep : boolean; @@ -46,9 +58,12 @@ signal fifo_write, last : std_logic; attribute syn_preserve of CLKt : signal is true; attribute syn_keep of CLKt : signal is true; +signal timer : unsigned(20 downto 0) := (others => '0'); begin +timer <= timer + 1 when rising_edge(CLK); + THE_PLL : entity work.pll_4x266 port map( CLKI => CLK, @@ -61,49 +76,107 @@ THE_PLL : entity work.pll_4x266 CLKa(3 downto 0) <= CLKt(3 downto 0); CLKa(7 downto 4) <= not CLKt(3 downto 0); -gen_ffarr_first : for i in 0 to 7 generate - ffarr(0)(i) <= SIGNAL_IN when rising_edge(CLKa(i)); - ffarr(1)(i) <= ffarr(0)(i) when rising_edge(CLKa((i/4)*4)); - ffarr(2)(i) <= ffarr(1)(i) when rising_edge(CLKa(0)); -end generate; + +gen_channels : for c in 0 to CHANNELS-1 generate + gen_ffarr_first : for i in 0 to 7 generate + ffarr(0)(c)(i) <= SIGNAL_IN(c) when rising_edge(CLKa(i)); + ffarr(1)(c)(i) <= ffarr(0)(c)(i) when rising_edge(CLKa((i/4)*4)); + ffarr(2)(c)(i) <= ffarr(1)(c)(i) when rising_edge(CLKa(0)); + end generate; process begin wait until falling_edge(CLK); - final_t <= ffarr(2); + final_t(c) <= ffarr(2)(c); end process; + process begin wait until rising_edge(CLK); - final1 <= final_t; - final2 <= ffarr(2); - last <= final2(7); - if (final1(7) xor last) = '1' then - fifo_write <= '1'; - final <= final1 & last; - elsif (final2(7) xor final1(7)) = '1' then - fifo_write <= '1'; - final <= final2 & final1(7); + final1(c) <= final_t(c); + final2(c) <= ffarr(2)(c); + last(c) <= final2(c)(7); + if (final1(c)(7) xor last(c)) = '1' then + fifo_write(c) <= '1'; + final(c) <= '0' & final1(c) & last(c); + elsif (final2(c)(7) xor final1(c)(7)) = '1' then + fifo_write(c) <= '1'; + final(c) <= '1' & final2(c) & final1(c)(7); else - fifo_write <= '0'; + fifo_write(c) <= '0'; end if; end process; + +process begin + wait until rising_edge(CLK); + if fifo_write(c) = '1' then + finalval(c) <= (others => '0'); + case final(c)(7 downto 0) is + when x"01" | x"fe" => finalval(c)(2 downto 0) <= "000"; + when x"03" | x"fc" => finalval(c)(2 downto 0) <= "001"; + when x"07" | x"f8" => finalval(c)(2 downto 0) <= "010"; + when x"0f" | x"f0" => finalval(c)(2 downto 0) <= "011"; + when x"1f" | x"e0" => finalval(c)(2 downto 0) <= "100"; + when x"3f" | x"c0" => finalval(c)(2 downto 0) <= "101"; + when x"7f" | x"80" => finalval(c)(2 downto 0) <= "110"; + when x"ff" | x"00" => finalval(c)(2 downto 0) <= "111"; + when others => finalval(c)(3) <= '1'; + end case; + finalval(c)(5) <= final(c)(9); + finalval(c)(4) <= final(c)(8); + fifo_write_val(c) <= '1'; + else + fifo_write_val(c) <= '0'; + end if; +end process; + +end generate; -THE_FIFO : entity work.fifo_9x2k_oreg +process + variable chan : integer range 0 to 16 := 0; +begin + wait until rising_edge(CLK); + chan := to_integer(unsigned(SELECT_IN)); + fifo_real_write <= '0'; + if fifo_write_val(chan) = '1' then + fifo_data(3 downto 0) <= finalval(chan)(3 downto 0); + fifo_data(4) <= finalval(chan)(5); + fifo_data(25 downto 5) <= std_logic_vector(timer(20 downto 0)); +-- fifo_data(27 downto 25) <= std_logic_vector(to_unsigned(chan,3)); + fifo_data(29 downto 26) <= SELECT_IN; + fifo_data(30) <= finalval(chan)(4); + fifo_real_write <= '1'; + end if; +-- chan := chan + 1; +-- if chan = 9 then chan := 0; end if; +end process; + + +THE_FIFO : entity work.fifo_36x1k port map( - Data => final, + Data => fifo_data, WrClock => CLK, RdClock => CLK, - WrEn => fifo_write, + WrEn => fifo_real_write, RdEn => READ_IN, Reset => RESET_IN, RPReset => RESET_IN, - Q => DATA_OUT, - Empty => EMPTY_OUT, + Q => fifo_data_out, + Empty => fifo_empty, Full => open, AlmostEmpty => open, AlmostFull => open ); + +process begin + wait until rising_edge(CLK); + if READ_IN = '1' then + valid_read <= not fifo_empty; + end if; +end process; + +EMPTY_OUT <= fifo_empty; +DATA_OUT <= valid_read & fifo_data_out(30 downto 0); end architecture; \ No newline at end of file -- 2.43.0