]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Mupix Word Unpacker
authorTobias Weber <toweber86@gmail.com>
Thu, 31 May 2018 08:46:23 +0000 (10:46 +0200)
committerTobias Weber <toweber86@gmail.com>
Thu, 31 May 2018 08:46:23 +0000 (10:46 +0200)
mupix/Mupix8/sources/MuPixUnpacker.vhd [new file with mode: 0644]

diff --git a/mupix/Mupix8/sources/MuPixUnpacker.vhd b/mupix/Mupix8/sources/MuPixUnpacker.vhd
new file mode 100644 (file)
index 0000000..cd4ccb7
--- /dev/null
@@ -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;