From: Tobias Weber Date: Thu, 31 May 2018 08:46:23 +0000 (+0200) Subject: Mupix Word Unpacker X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=9e6205ad086dca4d0416ffb967a7beeb38d073a5;p=trb3.git Mupix Word Unpacker --- diff --git a/mupix/Mupix8/sources/MuPixUnpacker.vhd b/mupix/Mupix8/sources/MuPixUnpacker.vhd new file mode 100644 index 0000000..cd4ccb7 --- /dev/null +++ b/mupix/Mupix8/sources/MuPixUnpacker.vhd @@ -0,0 +1,181 @@ +-------------------------------------------------------------- +-- Data Unpacker for Mupix 8 on TRBv3 +-- T. Weber, Ruhr Universiaet Bochum +-- Code taken partly from Heidelberg firmware by Ann-Kathrin +-------------------------------------------------------------- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity MupixUnpacker is + generic( + g_hitsize : integer := 40; + g_countersize : integer := 32 + ); + port( + clk : in std_logic; -- clk input + reset : in std_logic; -- reset input + data_in : in std_logic_vector(7 downto 0); -- 10b8b decoded data + komma : in std_logic; -- komma word indicator + valid : in std_logic; -- incoming data valid + hit_out : out std_logic_vector(g_hitsize - 1 downto 0); -- mupix 8 word output + hit_enable : out std_logic; -- new hit word + coarsecounter : out std_logic_vector(g_countersize - 1 downto 0); --coarsecounter output + counter_enable : out std_logic; -- new counter value + link_flag : out std_logic; -- link flag + errorcounter : out std_logic_vector(31 downto 0)); -- error counter +end entity MupixUnpacker; + +architecture RTL of MupixUnpacker is + + type unpacker_fsm_type is (idle, receive_err, counter, link, data); + signal unpacker_state : unpacker_fsm_type := idle; + + signal data_i : std_logic_vector(31 downto 0); + signal errorcounter_i : unsigned(31 downto 0); + signal link_i : std_logic_vector(7 downto 0); + signal link_reg : std_logic_vector(7 downto 0); + signal link_toggle : std_logic; + signal data_mode : std_logic; + signal cnt4 : unsigned(1 downto 0); + signal counter_seen : std_logic; + signal coarse_reg : std_logic; + signal hit_reg : std_logic; + signal link_flag_reg : std_logic; + + constant k28_5 : std_logic_vector(7 downto 0) := x"bc"; + constant k28_0 : std_logic_vector(7 downto 0) := x"1c"; + +begin + + + errorcounter <= std_logic_vector(errorcounter_i); + + unpacker_proc : process (clk, reset) is + begin -- process unpacker_proc + if rising_edge(clk) then + if reset = '1' then + unpacker_state <= idle; + + hit_enable <= '0'; + hit_out <= (others => '0'); + coarsecounter <= (others => '0'); + counter_enable <= '0'; + link_flag <= '0'; + link_flag_reg <= '0'; + + link_i <= (others => '0'); + link_reg <= (others => '0'); + link_toggle <= '0'; + + errorcounter_i <= (others => '0'); + + cnt4 <= (others => '0'); + counter_seen <= '0'; + data_mode <= '0'; + else + link_flag_reg <= '0'; + coarse_reg <= '0'; + hit_reg <= '0'; + hit_enable <= hit_reg or coarse_reg; + counter_enable <= coarse_reg; + link_flag <= link_flag_reg; + + coarsecounter <= data_i(7 downto 0) & data_i(31 downto 8); + if coarse_reg = '1' then + hit_out <= data_i(31 downto 8) & link_i(3 downto 0) & x"3" & data_i(7 downto 0); + -- binary counter & link & x"3" & gray counter + elsif hit_reg = '1' then + hit_out <= link_i & data_i(7 downto 0) & data_i(31 downto 24) & data_i(23 downto 18) & data_i(17 downto 8); + -- Link & Row & Col & Charge & TS + end if; + + if valid = '0' then + link_reg <= (others => '0'); + link_toggle <= '0'; + unpacker_state <= idle; + else + data_i <= data_i(23 downto 0) & data_in; + case unpacker_state is + when idle => + cnt4 <= "00"; + link_toggle <= '0'; + if komma = '0' then -- indicates data or counter + if data_mode = '1' and counter_seen = '1' then + -- valid hit after link id and counter + unpacker_state <= data; + cnt4 <= "01"; + else + unpacker_state <= counter; + cnt4 <= "01"; + end if; + elsif komma = '1' and data_in = k28_0 then + unpacker_state <= link; + elsif komma = '1' and data_in = k28_5 then + unpacker_state <= idle; + else + unpacker_state <= receive_err; + end if; + + when counter => + if komma = '0' then + cnt4 <= cnt4 + 1; + if cnt4 = "11" then + coarse_reg <= '1'; + counter_seen <= '1'; + unpacker_state <= idle; + end if; + elsif komma = '1' and data_in = k28_5 then + unpacker_state <= idle; + else + unpacker_state <= receive_err; + end if; + + when link => + if komma = '0' then + if link_toggle = '0' then + link_reg <= data_in; + elsif link_reg = data_in then + link_i <= link_reg; + link_flag_reg <= '1'; + link_toggle <= '0'; + unpacker_state <= idle; + data_mode <= '1'; + counter_seen <= '0'; + else + unpacker_state <= receive_err; + end if; + elsif komma = '1' and data_in = k28_0 then + link_toggle <= '1'; + else + unpacker_state <= receive_err; + end if; + + when data => + if komma = '1' then + cnt4 <= cnt4 + 1; + if cnt4 = "11" then + hit_reg <= '1'; + unpacker_state <= idle; + elsif komma = '1' and data_in = k28_5 then + unpacker_state <= idle; + else + unpacker_state <= receive_err; + end if; + end if; + + when receive_err => + errorcounter_i <= errorcounter_i + 1; + if komma = '1' and data_in = k28_5 then + unpacker_state <= idle; + else + unpacker_state <= receive_err; + end if; + end case; + end if; + + end if; + end if; + end process unpacker_proc; + +end architecture RTL;