--- /dev/null
+--------------------------------------------------------------
+-- 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;