]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Bugfixes to trigger code.
authorTobias Weber <toweber86@gmail.com>
Thu, 3 May 2018 09:37:27 +0000 (11:37 +0200)
committerTobias Weber <toweber86@gmail.com>
Thu, 3 May 2018 09:37:27 +0000 (11:37 +0200)
mupix/Mupix8/sources/MupixTRBReadout.vhd
mupix/Mupix8/sources/ReadoutController.vhd
mupix/Mupix8/sources/TriggerHandler.vhd
mupix/Mupix8/tb/MupixTRBReadoutAndTriggerTest.vhd [new file with mode: 0644]

index 77e8d40f7ff6b06c8ccbdfa79e82e54922a5160a..dbf57f962c295451b46aec845fa56bf10da322a9 100644 (file)
@@ -8,363 +8,363 @@ use ieee.std_logic_1164.all;
 use ieee.numeric_std.all;
 
 entity MupixTRBReadout is
-       generic(g_mupix_links           : natural := 4; -- number of input data channels from mupix
-               g_cyc_mem_address_width : integer := 13; -- memory depth of circular buffer
-               g_datawidth             : integer := 32 -- width of data words
-              );
-       port(
-               clk                  : in  std_logic; -- clock input
-               rst                  : in  std_logic; -- reset input
-               -- input fifo signals (maybe we need word width conversion somewhere ?)
-               fifo_empty           : in  std_logic_vector(g_mupix_links - 1 downto 0);
-               fifo_full            : in  std_logic_vector(g_mupix_links - 1 downto 0);
-               fifo_datain          : in  std_logic_vector(g_mupix_links*g_datawidth - 1 downto 0);
-               fifo_rden            : out std_logic_vector(g_mupix_links - 1 downto 0);
-               -- readout and trigger
-               trb_trigger          : in  std_logic; -- signal from trb to start readout
-               dataout              : out std_logic_vector(g_datawidth - 1 downto 0); -- data to TRB data channel
-               data_valid           : out std_logic; -- output data is valid
-               busy                 : out std_logic; -- readout controller is busy
-               -- TRB slow Control channel
-               SLV_READ_IN          : in  std_logic;
-               SLV_WRITE_IN         : in  std_logic;
-               SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
-               SLV_DATA_IN          : in  std_logic_vector(31 downto 0);
-               SLV_ADDR_IN          : in  std_logic_vector(15 downto 0);
-               SLV_ACK_OUT          : out std_logic;
-               SLV_NO_MORE_DATA_OUT : out std_logic;
-               SLV_UNKNOWN_ADDR_OUT : out std_logic);
+  generic(g_mupix_links           : natural := 4;  -- number of input data channels from mupix
+          g_cyc_mem_address_width : integer := 13;  -- memory depth of circular buffer
+          g_datawidth             : integer := 32  -- width of data words
+          );
+  port(
+    clk                  : in  std_logic;  -- clock input
+    rst                  : in  std_logic;  -- reset input
+    -- input fifo signals (maybe we need word width conversion somewhere ?)
+    fifo_empty           : in  std_logic_vector(g_mupix_links - 1 downto 0);
+    fifo_full            : in  std_logic_vector(g_mupix_links - 1 downto 0);
+    fifo_datain          : in  std_logic_vector(g_mupix_links*g_datawidth - 1 downto 0);
+    fifo_rden            : out std_logic_vector(g_mupix_links - 1 downto 0);
+    -- readout and trigger
+    trb_trigger          : in  std_logic;  -- signal from trb to start readout
+    dataout              : out std_logic_vector(g_datawidth - 1 downto 0);  -- data to TRB data channel
+    data_valid           : out std_logic;  -- output data is valid
+    busy                 : out std_logic;  -- readout controller is busy
+    -- TRB slow Control channel
+    SLV_READ_IN          : in  std_logic;
+    SLV_WRITE_IN         : in  std_logic;
+    SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
+    SLV_DATA_IN          : in  std_logic_vector(31 downto 0);
+    SLV_ADDR_IN          : in  std_logic_vector(15 downto 0);
+    SLV_ACK_OUT          : out std_logic;
+    SLV_NO_MORE_DATA_OUT : out std_logic;
+    SLV_UNKNOWN_ADDR_OUT : out std_logic);
 end entity MupixTRBReadout;
 
 
 architecture rtl of MupixTRBReadout is
 
-       component CircularMemory
-               generic(
-                       g_datawidth    : integer := 32;
-                       g_addresswidth : integer := 10;
-                       g_clockspeed   : integer := 1e8;
-                       g_boundedbuf   : boolean := false
-               );
-               port(
-                       clk          : in  std_logic;
-                       rst          : in  std_logic;
-                       wr_en        : in  std_logic;
-                       data_in      : in  std_logic_vector(g_datawidth - 1 downto 0);
-                       rd_en        : in  std_logic;
-                       offset_en    : in  std_logic;
-                       offset       : in  std_logic_vector(g_addresswidth - 1 downto 0);
-                       data_out     : out std_logic_vector(g_datawidth - 1 downto 0);
-                       empty        : out std_logic;
-                       full         : out std_logic;
-                       almost_empty : out std_logic;
-                       almost_full  : out std_logic;
-                       fillcnt      : out std_logic_vector(g_addresswidth downto 0);
-                       inword_freq  : out std_logic_vector(31 downto 0);
-                       outword_freq : out std_logic_vector(31 downto 0)
-               );
-       end component CircularMemory;
-       
-       component FiFoDataMux
-               generic(
-                       g_datawidth  : integer := 32; 
-                       g_inputs     : integer := 4;
-                       g_clockspeed : integer := 1e8
-               );
-               port(
-                       clk         : in  std_logic;
-                       rst         : in  std_logic;
-                       fifo_empty  : in  std_logic_vector(g_inputs - 1 downto 0);
-                       fifo_full   : in  std_logic_vector(g_inputs - 1 downto 0);
-                       fifo_datain : in  std_logic_vector(g_inputs*g_datawidth - 1 downto 0);
-                       fifo_mask   : in  std_logic_vector(g_inputs - 1 downto 0);
-                       fifo_rden   : out std_logic_vector(g_inputs - 1 downto 0);
-                       buff_wren   : out std_logic;
-                       dataout     : out std_logic_vector(g_datawidth - 1 downto 0);
-                       wordin_freq : out std_logic_vector(32*g_inputs - 1 downto 0);
-                       fifo_full_o : out std_logic
-               );
-       end component FiFoDataMux;
-       
-       component ReadoutController
-               generic(
-                       g_datawidth    : integer := 32;
-                       g_addresswidth : integer := 10
-               );
-               port(
-                       clk               : in  std_logic;
-                       rst               : in  std_logic;
-                       start             : in  std_logic;
-                       mode              : in  std_logic_vector(1 downto 0);
-                       writes_after_trig : in  std_logic_vector(g_addresswidth - 1 downto 0);
-                       max_words         : in  std_logic_vector(g_addresswidth - 1 downto 0);
-                       data_in           : in  std_logic_vector(g_datawidth - 1 downto 0);
-                       empty             : in  std_logic;
-                       almost_empty      : in  std_logic;
-                       sensor_id         : in  std_logic_vector(g_datawidth - 1 downto 0);
-                       offset_en         : out std_logic;
-                       rd_en             : out std_logic;
-                       busy              : out std_logic;
-                       data_valid        : out std_logic;
-                       data_out          : out std_logic_vector(g_datawidth - 1 downto 0)
-               );
-       end component ReadoutController;
-       
-       signal readout_mode_i          : std_logic_vector(1 downto 0)                           := "00";
-       signal readout_writes_aft_trig : std_logic_vector(g_cyc_mem_address_width - 1 downto 0) := (others => '0');
-       signal readout_words           : std_logic_vector(g_cyc_mem_address_width - 1 downto 0) := (others => '0');
-       signal sensor_id               : std_logic_vector(31 downto 0)                          := (others => '0');
-       signal multiplexer_mask        : std_logic_vector(g_mupix_links - 1 downto 0)           := (others => '0');
-       signal multiplexer_channel_sel : integer range 0 to g_mupix_links - 1                   := 0;
-       signal wordin_freq             : std_logic_vector(32*g_mupix_links - 1 downto 0)        := (others => '0');
-       signal fifo_full_o             : std_logic;
-       
-       signal cycl_fillcnt            : std_logic_vector(g_cyc_mem_address_width downto 0);
-       signal cycl_inword_freq        : std_logic_vector(31 downto 0);
-       signal cycl_outword_freq       : std_logic_vector(31 downto 0);
-       signal cycl_empty              : std_logic;
-       signal cycl_full               : std_logic;
-       signal cycl_almost_empty       : std_logic;
-       
-       signal fifo_mux_wren     : std_logic;
-       signal fifo_mux_data_out : std_logic_vector(g_datawidth - 1 downto 0);
-       
-       signal start_readout_slow_to_buffer      : std_logic := '0';
-       signal start_readout                     : std_logic := '0';
-       signal readout_controller_data_in        : std_logic_vector(g_datawidth - 1 downto 0);
-       signal readout_controller_data_out       : std_logic_vector(g_datawidth - 1 downto 0);
-       signal readout_controller_busy           : std_logic;
-       signal readout_controller_offset_en      : std_logic;
-       signal readout_controller_rd_en          : std_logic;
-       signal readout_controller_data_valid     : std_logic;
-       
-       type slow_readout_fsm_type is (idle, waitstate);
-       signal slow_readout_fsm : slow_readout_fsm_type := idle;
-       signal slow_data        : std_logic_vector(g_datawidth - 1 downto 0) := (others => '0');
-       signal start_slow_read  : std_logic := '0';
-       signal slow_read_busy   : std_logic := '0';
-       signal slow_read_done   : std_logic := '0';
-       
+  component CircularMemory
+    generic(
+      g_datawidth    : integer := 32;
+      g_addresswidth : integer := 10;
+      g_clockspeed   : integer := 1e8;
+      g_boundedbuf   : boolean := false
+      );
+    port(
+      clk          : in  std_logic;
+      rst          : in  std_logic;
+      wr_en        : in  std_logic;
+      data_in      : in  std_logic_vector(g_datawidth - 1 downto 0);
+      rd_en        : in  std_logic;
+      offset_en    : in  std_logic;
+      offset       : in  std_logic_vector(g_addresswidth - 1 downto 0);
+      data_out     : out std_logic_vector(g_datawidth - 1 downto 0);
+      empty        : out std_logic;
+      full         : out std_logic;
+      almost_empty : out std_logic;
+      almost_full  : out std_logic;
+      fillcnt      : out std_logic_vector(g_addresswidth downto 0);
+      inword_freq  : out std_logic_vector(31 downto 0);
+      outword_freq : out std_logic_vector(31 downto 0)
+      );
+  end component CircularMemory;
+
+  component FiFoDataMux
+    generic(
+      g_datawidth  : integer := 32;
+      g_inputs     : integer := 4;
+      g_clockspeed : integer := 1e8
+      );
+    port(
+      clk         : in  std_logic;
+      rst         : in  std_logic;
+      fifo_empty  : in  std_logic_vector(g_inputs - 1 downto 0);
+      fifo_full   : in  std_logic_vector(g_inputs - 1 downto 0);
+      fifo_datain : in  std_logic_vector(g_inputs*g_datawidth - 1 downto 0);
+      fifo_mask   : in  std_logic_vector(g_inputs - 1 downto 0);
+      fifo_rden   : out std_logic_vector(g_inputs - 1 downto 0);
+      buff_wren   : out std_logic;
+      dataout     : out std_logic_vector(g_datawidth - 1 downto 0);
+      wordin_freq : out std_logic_vector(32*g_inputs - 1 downto 0);
+      fifo_full_o : out std_logic
+      );
+  end component FiFoDataMux;
+
+  component ReadoutController
+    generic(
+      g_datawidth    : integer := 32;
+      g_addresswidth : integer := 10
+      );
+    port(
+      clk               : in  std_logic;
+      rst               : in  std_logic;
+      start             : in  std_logic;
+      mode              : in  std_logic_vector(1 downto 0);
+      writes_after_trig : in  std_logic_vector(g_addresswidth - 1 downto 0);
+      max_words         : in  std_logic_vector(g_addresswidth - 1 downto 0);
+      data_in           : in  std_logic_vector(g_datawidth - 1 downto 0);
+      empty             : in  std_logic;
+      almost_empty      : in  std_logic;
+      sensor_id         : in  std_logic_vector(g_datawidth - 1 downto 0);
+      offset_en         : out std_logic;
+      rd_en             : out std_logic;
+      busy              : out std_logic;
+      data_valid        : out std_logic;
+      data_out          : out std_logic_vector(g_datawidth - 1 downto 0)
+      );
+  end component ReadoutController;
+
+  signal readout_mode_i          : std_logic_vector(1 downto 0)                           := "00";
+  signal readout_writes_aft_trig : std_logic_vector(g_cyc_mem_address_width - 1 downto 0) := (others => '0');
+  signal readout_words           : std_logic_vector(g_cyc_mem_address_width - 1 downto 0) := (others => '0');
+  signal sensor_id               : std_logic_vector(31 downto 0)                          := (others => '0');
+  signal multiplexer_mask        : std_logic_vector(g_mupix_links - 1 downto 0)           := (others => '0');
+  signal multiplexer_channel_sel : integer range 0 to g_mupix_links - 1                   := 0;
+  signal wordin_freq             : std_logic_vector(32*g_mupix_links - 1 downto 0)        := (others => '0');
+  signal fifo_full_o             : std_logic;
+
+  signal cycl_fillcnt      : std_logic_vector(g_cyc_mem_address_width downto 0);
+  signal cycl_inword_freq  : std_logic_vector(31 downto 0);
+  signal cycl_outword_freq : std_logic_vector(31 downto 0);
+  signal cycl_empty        : std_logic;
+  signal cycl_full         : std_logic;
+  signal cycl_almost_empty : std_logic;
+
+  signal fifo_mux_wren     : std_logic;
+  signal fifo_mux_data_out : std_logic_vector(g_datawidth - 1 downto 0);
+
+  signal start_readout_slow_to_buffer  : std_logic := '0';
+  signal start_readout                 : std_logic := '0';
+  signal readout_controller_data_in    : std_logic_vector(g_datawidth - 1 downto 0);
+  signal readout_controller_data_out   : std_logic_vector(g_datawidth - 1 downto 0);
+  signal readout_controller_busy       : std_logic;
+  signal readout_controller_offset_en  : std_logic;
+  signal readout_controller_rd_en      : std_logic;
+  signal readout_controller_data_valid : std_logic;
+
+  type slow_readout_fsm_type is (idle, waitstate);
+  signal slow_readout_fsm : slow_readout_fsm_type                      := idle;
+  signal slow_data        : std_logic_vector(g_datawidth - 1 downto 0) := (others => '0');
+  signal start_slow_read  : std_logic                                  := '0';
+  signal slow_read_busy   : std_logic                                  := '0';
+  signal slow_read_done   : std_logic                                  := '0';
+
 begin
-       
-       start_readout <= start_readout_slow_to_buffer or trb_trigger; 
-       
-       data_mux_1 : entity work.FiFoDataMux
-               generic map(
-                       g_datawidth  => g_datawidth,
-                       g_inputs     => g_mupix_links,
-                       g_clockspeed => 1e8
-               )
-               port map(
-                       clk         => clk,
-                       rst         => rst,
-                       fifo_empty  => fifo_empty,
-                       fifo_full   => fifo_full,
-                       fifo_datain => fifo_datain,
-                       fifo_mask   => multiplexer_mask,
-                       fifo_rden   => fifo_rden,
-                       buff_wren   => fifo_mux_wren,
-                       dataout     => fifo_mux_data_out,
-                       wordin_freq => wordin_freq,
-                       fifo_full_o => fifo_full_o
-               );
-       
-       cycl_buffer_1 : entity work.CircularMemory
-               generic map(
-                       g_datawidth    => g_datawidth,
-                       g_addresswidth => g_cyc_mem_address_width,
-                       g_clockspeed   => 1e8,
-                       g_boundedbuf   => false
-               )
-               port map(
-                       clk          => clk,
-                       rst          => rst,
-                       wr_en        => fifo_mux_wren,
-                       data_in      => fifo_mux_data_out,
-                       rd_en        => readout_controller_rd_en,
-                       offset_en    => readout_controller_offset_en,
-                       offset       => readout_words,
-                       data_out     => readout_controller_data_in,
-                       empty        => cycl_empty,
-                       full         => cycl_full,
-                       almost_empty => cycl_almost_empty,
-                       almost_full  => open,
-                       fillcnt      => cycl_fillcnt,
-                       inword_freq  => cycl_inword_freq,
-                       outword_freq => cycl_outword_freq
-               );
-       
-       readout_controller_1 : entity work.ReadoutController
-               generic map(
-                       g_datawidth    => g_datawidth,
-                       g_addresswidth => g_cyc_mem_address_width
-               )
-               port map(
-                       clk               => clk,
-                       rst               => rst,
-                       start             => start_readout,
-                       mode              => readout_mode_i,
-                       writes_after_trig => readout_writes_aft_trig,
-                       max_words         => readout_words,
-                       data_in           => readout_controller_data_in,
-                       empty             => cycl_empty,
-                       almost_empty      => cycl_almost_empty,
-                       sensor_id         => sensor_id,
-                       offset_en         => readout_controller_offset_en,
-                       rd_en             => readout_controller_rd_en,
-                       busy              => readout_controller_busy,
-                       data_valid        => readout_controller_data_valid,
-                       data_out          => readout_controller_data_out
-               );
-       
-       data_read_slow : process (clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               slow_readout_fsm             <= idle;
-                               slow_read_done               <= '0';
-                               slow_read_busy               <= '0';
-                               start_readout_slow_to_buffer <= '0';
-                       else
-                               start_readout_slow_to_buffer <= '0';
-                               slow_read_done   <= '0';
-                               case slow_readout_fsm is 
-                                       when idle =>
-                                               slow_readout_fsm <= idle;
-                                               slow_read_busy   <= '0';
-                                               if start_slow_read = '1' then
-                                                       start_readout_slow_to_buffer <= '1';
-                                                       slow_read_busy               <= '1';
-                                                       slow_data                    <= (others => '0');
-                                                       slow_readout_fsm             <= waitstate;
-                                               end if;
-                                       when waitstate =>
-                                               slow_read_busy <= '1';
-                                               if readout_controller_data_valid = '1' then
-                                                       slow_read_done   <= '1';
-                                                       slow_data        <= readout_controller_data_out;
-                                                       slow_readout_fsm <= idle;
-                                               end if;
-                               end case;
-                       end if;
-               end if;
-       end process data_read_slow;
-       
-       
-       ------------------------------------------------------------------------------------
-       --Slow Control Handling
-       ------------------------------------------------------------------------------------
-       --0x100: readout controller mode
-       --0x101: readout controller writes after trigger
-       --0x102: readout controller numbers of words to readout
-       --0x103: readout controller sensor id
-       --0x104: readout controller start slow readout (read only)
-       --0x105: fifo multiplexer mask
-       --0x106: fifo multiplexer input frequency (write select channel, read frequency)
-       --0x107: fifo multiplexer full (read-only)
-       --0x108: circular memory empty/full flags, fill cnt (read-only)
-       --0x109: circular memory input word frequency (read-only)
-       --0x10a: circular memory output word frequency (read-only)
-       --0x10b: readout controller read-enable (debug read-only)
-       -----------------------------------------------------------------------------------
-       slv_bus_handler : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               SLV_DATA_OUT         <= (others => '0');
-                               SLV_ACK_OUT          <= '0';
-                               SLV_NO_MORE_DATA_OUT <= '0';
-                               SLV_UNKNOWN_ADDR_OUT <= '0';
-                               start_slow_read      <= '0';
-                       else
-                               SLV_DATA_OUT         <= (others => '0');
-                               SLV_ACK_OUT          <= '0';
-                               SLV_NO_MORE_DATA_OUT <= '0';
-                               SLV_UNKNOWN_ADDR_OUT <= '0';
-                               start_slow_read      <= '0';
-                               
-                               if slow_read_busy = '1' then
-                                       if slow_read_done = '1' then
-                                               SLV_DATA_OUT <= slow_data;
-                                               SLV_ACK_OUT  <= '1';
-                                       end if;
-                               
-                               elsif SLV_WRITE_IN = '1' then
-                                       case SLV_ADDR_IN is
-                                               when x"0100" =>
-                                                       readout_mode_i <= SLV_DATA_IN(1 downto 0);
-                                                       SLV_ACK_OUT    <= '1';
-                                               when x"0101" =>
-                                                       readout_writes_aft_trig <= SLV_DATA_IN(g_cyc_mem_address_width - 1 downto 0);
-                                                       SLV_ACK_OUT             <= '1';
-                                               when x"0102" =>
-                                                       readout_words           <= SLV_DATA_IN(g_cyc_mem_address_width - 1 downto 0);
-                                                       SLV_ACK_OUT             <= '1';
-                                               when x"0103" =>
-                                                       sensor_id   <= SLV_DATA_IN;
-                                                       SLV_ACK_OUT <= '1';
-                                               when x"0105" =>
-                                                       multiplexer_mask <= SLV_DATA_IN(g_mupix_links - 1 downto 0);
-                                                       SLV_ACK_OUT      <= '1';
-                                               when x"0106" =>
-                                                       multiplexer_channel_sel <= to_integer(unsigned(SLV_DATA_IN));
-                                                       SLV_ACK_OUT             <= '1';
-                                               when others =>
-                                                       slv_unknown_addr_out <= '1';
-                                       end case;
-                               elsif SLV_READ_IN = '1' then
-                                       case SLV_ADDR_IN is
-                                               when x"0100" =>
-                                                       SLV_DATA_OUT(1 downto 0) <= readout_mode_i;
-                                                       SLV_ACK_OUT              <= '1';
-                                               when x"0101" =>
-                                                       SLV_DATA_OUT(g_cyc_mem_address_width - 1 downto 0) <= readout_writes_aft_trig;
-                                                       SLV_ACK_OUT                                        <= '1';
-                                               when x"0102" =>
-                                                       SLV_DATA_OUT(g_cyc_mem_address_width - 1 downto 0) <= readout_words;
-                                                       SLV_ACK_OUT                                        <= '1';
-                                               when x"0103" =>
-                                                       SLV_DATA_OUT <= sensor_id;
-                                                       SLV_ACK_OUT  <= '1';
-                                               when x"0104" =>
-                                                       if cycl_empty = '0' and readout_mode_i = "00" then
-                                                               start_slow_read <= '1';
-                                                       else
-                                                               SLV_NO_MORE_DATA_OUT <= '1';
-                                                       end if;
-                                               when x"0105" =>
-                                                       SLV_DATA_OUT(g_mupix_links - 1 downto 0)       <= multiplexer_mask;
-                                                       SLV_ACK_OUT                                    <= '1';
-                                               when x"0106" =>
-                                                       SLV_DATA_OUT <= wordin_freq((multiplexer_channel_sel + 1)*32 - 1 downto multiplexer_channel_sel*32);
-                                                       SLV_ACK_OUT  <= '1';
-                                               when x"0107" =>
-                                                       SLV_DATA_OUT(0) <= fifo_full_o;
-                                                       SLV_ACK_OUT     <= '1';
-                                               when x"0108" =>
-                                                       SLV_DATA_OUT(g_cyc_mem_address_width downto 0) <= cycl_fillcnt;
-                                                       SLV_DATA_OUT(31)      <= cycl_empty;
-                                                       SLV_DATA_OUT(30)      <= cycl_full;
-                                                       SLV_ACK_OUT                                    <= '1';
-                                               when x"0109" =>
-                                                       SLV_DATA_OUT <= cycl_inword_freq;
-                                                       SLV_ACK_OUT     <= '1';
-                                               when x"010a" =>
-                                                       SLV_DATA_OUT <= cycl_outword_freq;
-                                                       SLV_ACK_OUT     <= '1';
-                        when x"010b" =>
-                                                       SLV_DATA_OUT(3 downto 0) <= busy & start_readout & start_readout_slow_to_buffer & trb_trigger;
-                                                       SLV_ACK_OUT              <= '1';
-                                               when others =>
-                                                       slv_unknown_addr_out <= '1';
-                                       end case;
-                               end if;
-                       end if;
-               end if;
-       end process slv_bus_handler;
-       
-       busy <= readout_controller_busy;
-       dataout <= readout_controller_data_out;
-       data_valid <= readout_controller_data_valid;
-       
+
+  start_readout <= start_readout_slow_to_buffer or trb_trigger;
+
+  data_mux_1 : entity work.FiFoDataMux
+    generic map(
+      g_datawidth  => g_datawidth,
+      g_inputs     => g_mupix_links,
+      g_clockspeed => 1e8
+      )
+    port map(
+      clk         => clk,
+      rst         => rst,
+      fifo_empty  => fifo_empty,
+      fifo_full   => fifo_full,
+      fifo_datain => fifo_datain,
+      fifo_mask   => multiplexer_mask,
+      fifo_rden   => fifo_rden,
+      buff_wren   => fifo_mux_wren,
+      dataout     => fifo_mux_data_out,
+      wordin_freq => wordin_freq,
+      fifo_full_o => fifo_full_o
+      );
+
+  cycl_buffer_1 : entity work.CircularMemory
+    generic map(
+      g_datawidth    => g_datawidth,
+      g_addresswidth => g_cyc_mem_address_width,
+      g_clockspeed   => 1e8,
+      g_boundedbuf   => false
+      )
+    port map(
+      clk          => clk,
+      rst          => rst,
+      wr_en        => fifo_mux_wren,
+      data_in      => fifo_mux_data_out,
+      rd_en        => readout_controller_rd_en,
+      offset_en    => readout_controller_offset_en,
+      offset       => readout_words,
+      data_out     => readout_controller_data_in,
+      empty        => cycl_empty,
+      full         => cycl_full,
+      almost_empty => cycl_almost_empty,
+      almost_full  => open,
+      fillcnt      => cycl_fillcnt,
+      inword_freq  => cycl_inword_freq,
+      outword_freq => cycl_outword_freq
+      );
+
+  readout_controller_1 : entity work.ReadoutController
+    generic map(
+      g_datawidth    => g_datawidth,
+      g_addresswidth => g_cyc_mem_address_width
+      )
+    port map(
+      clk               => clk,
+      rst               => rst,
+      start             => start_readout,
+      mode              => readout_mode_i,
+      writes_after_trig => readout_writes_aft_trig,
+      max_words         => readout_words,
+      data_in           => readout_controller_data_in,
+      empty             => cycl_empty,
+      almost_empty      => cycl_almost_empty,
+      sensor_id         => sensor_id,
+      offset_en         => readout_controller_offset_en,
+      rd_en             => readout_controller_rd_en,
+      busy              => readout_controller_busy,
+      data_valid        => readout_controller_data_valid,
+      data_out          => readout_controller_data_out
+      );
+
+  data_read_slow : process (clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        slow_readout_fsm             <= idle;
+        slow_read_done               <= '0';
+        slow_read_busy               <= '0';
+        start_readout_slow_to_buffer <= '0';
+      else
+        start_readout_slow_to_buffer <= '0';
+        slow_read_done               <= '0';
+        case slow_readout_fsm is
+          when idle =>
+            slow_readout_fsm <= idle;
+            slow_read_busy   <= '0';
+            if start_slow_read = '1' then
+              start_readout_slow_to_buffer <= '1';
+              slow_read_busy               <= '1';
+              slow_data                    <= (others => '0');
+              slow_readout_fsm             <= waitstate;
+            end if;
+          when waitstate =>
+            slow_read_busy <= '1';
+            if readout_controller_data_valid = '1' then
+              slow_read_done   <= '1';
+              slow_data        <= readout_controller_data_out;
+              slow_readout_fsm <= idle;
+            end if;
+        end case;
+      end if;
+    end if;
+  end process data_read_slow;
+
+
+  ------------------------------------------------------------------------------------
+  --Slow Control Handling
+  ------------------------------------------------------------------------------------
+  --0x100: readout controller mode
+  --0x101: readout controller writes after trigger
+  --0x102: readout controller numbers of words to readout
+  --0x103: readout controller sensor id
+  --0x104: readout controller start slow readout (read only)
+  --0x105: fifo multiplexer mask
+  --0x106: fifo multiplexer input frequency (write select channel, read frequency)
+  --0x107: fifo multiplexer full (read-only)
+  --0x108: circular memory empty/full flags, fill cnt (read-only)
+  --0x109: circular memory input word frequency (read-only)
+  --0x10a: circular memory output word frequency (read-only)
+  --0x10b: readout controller read-enable (debug read-only)
+  -----------------------------------------------------------------------------------
+  slv_bus_handler : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        SLV_DATA_OUT         <= (others => '0');
+        SLV_ACK_OUT          <= '0';
+        SLV_NO_MORE_DATA_OUT <= '0';
+        SLV_UNKNOWN_ADDR_OUT <= '0';
+        start_slow_read      <= '0';
+      else
+        SLV_DATA_OUT         <= (others => '0');
+        SLV_ACK_OUT          <= '0';
+        SLV_NO_MORE_DATA_OUT <= '0';
+        SLV_UNKNOWN_ADDR_OUT <= '0';
+        start_slow_read      <= '0';
+
+        if slow_read_busy = '1' then
+          if slow_read_done = '1' then
+            SLV_DATA_OUT <= slow_data;
+            SLV_ACK_OUT  <= '1';
+          end if;
+
+        elsif SLV_WRITE_IN = '1' then
+          case SLV_ADDR_IN is
+            when x"0100" =>
+              readout_mode_i <= SLV_DATA_IN(1 downto 0);
+              SLV_ACK_OUT    <= '1';
+            when x"0101" =>
+              readout_writes_aft_trig <= SLV_DATA_IN(g_cyc_mem_address_width - 1 downto 0);
+              SLV_ACK_OUT             <= '1';
+            when x"0102" =>
+              readout_words <= SLV_DATA_IN(g_cyc_mem_address_width - 1 downto 0);
+              SLV_ACK_OUT   <= '1';
+            when x"0103" =>
+              sensor_id   <= SLV_DATA_IN;
+              SLV_ACK_OUT <= '1';
+            when x"0105" =>
+              multiplexer_mask <= SLV_DATA_IN(g_mupix_links - 1 downto 0);
+              SLV_ACK_OUT      <= '1';
+            when x"0106" =>
+              multiplexer_channel_sel <= to_integer(unsigned(SLV_DATA_IN));
+              SLV_ACK_OUT             <= '1';
+            when others =>
+              slv_unknown_addr_out <= '1';
+          end case;
+        elsif SLV_READ_IN = '1' then
+          case SLV_ADDR_IN is
+            when x"0100" =>
+              SLV_DATA_OUT(1 downto 0) <= readout_mode_i;
+              SLV_ACK_OUT              <= '1';
+            when x"0101" =>
+              SLV_DATA_OUT(g_cyc_mem_address_width - 1 downto 0) <= readout_writes_aft_trig;
+              SLV_ACK_OUT                                        <= '1';
+            when x"0102" =>
+              SLV_DATA_OUT(g_cyc_mem_address_width - 1 downto 0) <= readout_words;
+              SLV_ACK_OUT                                        <= '1';
+            when x"0103" =>
+              SLV_DATA_OUT <= sensor_id;
+              SLV_ACK_OUT  <= '1';
+            when x"0104" =>
+              if cycl_empty = '0' and readout_mode_i = "00" then
+                start_slow_read <= '1';
+              else
+                SLV_NO_MORE_DATA_OUT <= '1';
+              end if;
+            when x"0105" =>
+              SLV_DATA_OUT(g_mupix_links - 1 downto 0) <= multiplexer_mask;
+              SLV_ACK_OUT                              <= '1';
+            when x"0106" =>
+              SLV_DATA_OUT <= wordin_freq((multiplexer_channel_sel + 1)*32 - 1 downto multiplexer_channel_sel*32);
+              SLV_ACK_OUT  <= '1';
+            when x"0107" =>
+              SLV_DATA_OUT(0) <= fifo_full_o;
+              SLV_ACK_OUT     <= '1';
+            when x"0108" =>
+              SLV_DATA_OUT(g_cyc_mem_address_width downto 0) <= cycl_fillcnt;
+              SLV_DATA_OUT(31)                               <= cycl_empty;
+              SLV_DATA_OUT(30)                               <= cycl_full;
+              SLV_ACK_OUT                                    <= '1';
+            when x"0109" =>
+              SLV_DATA_OUT <= cycl_inword_freq;
+              SLV_ACK_OUT  <= '1';
+            when x"010a" =>
+              SLV_DATA_OUT <= cycl_outword_freq;
+              SLV_ACK_OUT  <= '1';
+            when x"010b" =>
+              SLV_DATA_OUT(3 downto 0) <= readout_controller_busy & start_readout & start_readout_slow_to_buffer & trb_trigger;
+              SLV_ACK_OUT              <= '1';
+            when others =>
+              slv_unknown_addr_out <= '1';
+          end case;
+        end if;
+      end if;
+    end if;
+  end process slv_bus_handler;
+
+  busy       <= readout_controller_busy;
+  dataout    <= readout_controller_data_out;
+  data_valid <= readout_controller_data_valid;
+
 end architecture;
index fcc04f6e6e677ed8a14fc1471c10b3eb20d86036..3206e58900f20e8f51102a34f60247f6274bf41c 100644 (file)
@@ -16,195 +16,195 @@ use ieee.numeric_std.all;
 -----------------------------------------------------------------------------
 
 entity ReadoutController is
-       generic(
-               g_datawidth    : integer := 32; -- width of data words
-               g_addresswidth : integer := 10  -- width of address pointers, number of words is 2**g_addresswidth
-       );
-       port(
-               clk               : in  std_logic; -- clock input
-               rst               : in  std_logic; -- reset input 
-               start             : in  std_logic; -- start reading
-               mode              : in  std_logic_vector(1 downto 0); -- readout mode
-               writes_after_trig : in  std_logic_vector(g_addresswidth - 1 downto 0); -- clock cycles after trigger before starting readout (needs to be at least two)
-               max_words         : in  std_logic_vector(g_addresswidth - 1 downto 0); -- maximum number of words to read
-               data_in           : in  std_logic_vector(g_datawidth - 1 downto 0); -- data from buffer
-               empty             : in  std_logic; --empty flag from circular buffer
-               almost_empty      : in  std_logic; --empty flag from circular buffer
-               sensor_id         : in  std_logic_vector(g_datawidth - 1 downto 0);
-               offset_en         : out std_logic; -- set offset between read and write pointer (offset value is set directly in circular buffer)
-               rd_en             : out std_logic; -- read enable to circular buffer
-               busy              : out std_logic; -- readout controller busy
-               data_valid        : out std_logic; -- data from readout controller valid
-               data_out          : out std_logic_vector(g_datawidth - 1 downto 0)); -- data from readout controller
+  generic(
+    g_datawidth    : integer := 32;     -- width of data words
+    g_addresswidth : integer := 10  -- width of address pointers, number of words is 2**g_addresswidth
+    );
+  port(
+    clk               : in  std_logic;  -- clock input
+    rst               : in  std_logic;  -- reset input 
+    start             : in  std_logic;  -- start reading
+    mode              : in  std_logic_vector(1 downto 0);  -- readout mode
+    writes_after_trig : in  std_logic_vector(g_addresswidth - 1 downto 0);  -- clock cycles after trigger before starting readout (needs to be at least two)
+    max_words         : in  std_logic_vector(g_addresswidth - 1 downto 0);  -- maximum number of words to read
+    data_in           : in  std_logic_vector(g_datawidth - 1 downto 0);  -- data from buffer
+    empty             : in  std_logic;  --empty flag from circular buffer
+    almost_empty      : in  std_logic;  --empty flag from circular buffer
+    sensor_id         : in  std_logic_vector(g_datawidth - 1 downto 0);
+    offset_en         : out std_logic;  -- set offset between read and write pointer (offset value is set directly in circular buffer)
+    rd_en             : out std_logic;  -- read enable to circular buffer
+    busy              : out std_logic;  -- readout controller busy
+    data_valid        : out std_logic;  -- data from readout controller valid
+    data_out          : out std_logic_vector(g_datawidth - 1 downto 0));  -- data from readout controller
 end entity ReadoutController;
 
 architecture RTL of ReadoutController is
 
-       constant c_frame_start : std_logic_vector(g_datawidth - 1 downto 0) := x"FABEABBA";
-       constant c_frame_end   : std_logic_vector(g_datawidth - 1 downto 0) := x"BEEFBEEF";
+  constant c_frame_start : std_logic_vector(g_datawidth - 1 downto 0) := x"FABEABBA";
+  constant c_frame_end   : std_logic_vector(g_datawidth - 1 downto 0) := x"BEEFBEEF";
 
-       --readout state type, in mode 1, 2 a header and trailer will be put 
-       --at beginning and end of readout frame
-       type t_readout_state_type is (idle, header, read_single, read, wait_memory, wait_trigger, trailer);
-       signal readout_fsm : t_readout_state_type := idle;
+  --readout state type, in mode 1, 2 a header and trailer will be put 
+  --at beginning and end of readout frame
+  type t_readout_state_type is (idle, header, read_single, read, wait_memory, wait_trigger, trailer);
+  signal readout_fsm : t_readout_state_type := idle;
 
-       signal wordcounter        : unsigned(g_addresswidth - 1 downto 0) := (others => '0');
-       signal framecounter       : unsigned(31 downto 0)                 := (others => '0');
-       signal headercounter      : integer range 0 to 2                  := 0;
-       signal trailercounter     : integer range 0 to 1                  := 0;
-       signal triggerwaitcounter : unsigned(g_addresswidth - 1 downto 0) := (others => '0');
-       signal almost_empty_edge  : std_logic_vector(1 downto 0)          := (others => '0');
+  signal wordcounter        : unsigned(g_addresswidth - 1 downto 0) := (others => '0');
+  signal framecounter       : unsigned(31 downto 0)                 := (others => '0');
+  signal headercounter      : integer range 0 to 2                  := 0;
+  signal trailercounter     : integer range 0 to 1                  := 0;
+  signal triggerwaitcounter : unsigned(g_addresswidth - 1 downto 0) := (others => '0');
+  signal almost_empty_edge  : std_logic_vector(1 downto 0)          := (others => '0');
 
 begin
 
-       edge_detection : process (clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               almost_empty_edge <= (others => '0');
-                       else
-                               almost_empty_edge <= almost_empty_edge(0) & almost_empty;
-                       end if;
-               end if;
-       end process edge_detection;
-       
+  edge_detection : process (clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        almost_empty_edge <= (others => '0');
+      else
+        almost_empty_edge <= almost_empty_edge(0) & almost_empty;
+      end if;
+    end if;
+  end process edge_detection;
 
-       readout_proc : process(clk) is
-       begin
-               if rising_edge(clk) then
-                       if rst = '1' then
-                               readout_fsm   <= idle;
-                               rd_en         <= '0';
-                               busy          <= '0';
-                               data_valid    <= '0';
-                               data_out      <= (others => '0');
-                               framecounter  <= (others => '0');
-                               headercounter <= 0;
-                       else
-                               busy       <= '0';
-                               data_valid <= '0';
-                               data_out   <= (others => '0');
-                               rd_en      <= '0';
-                               offset_en  <= '0';
-                               case readout_fsm is
-                                       when idle =>
-                                               trailercounter     <= 0;
-                                               wordcounter        <= (others => '0');
-                                               headercounter      <= 0;
-                                               triggerwaitcounter <= (others => '0');
-                                               headercounter      <= 0;
-                                               if start = '1' then
-                                                       busy  <= '1';
-                                                       if mode = "00" then
-                                                               if empty = '0' then
-                                                                       readout_fsm <= read_single;
-                                                               else
-                                                                       data_out    <= (others => '0');
-                                                                       data_valid  <= '1';
-                                                                       readout_fsm <= idle;
-                                                               end if;
-                                                       elsif mode = "01" then
-                                                               readout_fsm <= header;
-                                                       elsif mode = "10" then
-                                                               readout_fsm <= header;
-                                                       else
-                                                               readout_fsm <= idle;
-                                                       end if;
-                                               else
-                                                       readout_fsm <= idle;
-                                               end if;
-                                       when header =>
-                                               busy          <= '1';
-                                               data_valid    <= '1';
-                                               headercounter <= headercounter + 1;
-                                               case headercounter is
-                                                       when 0 =>
-                                                               data_out <= c_frame_start;
-                                                       when 1 =>
-                                                               data_out <= sensor_id;
-                                                       when 2 =>
-                                                               data_out     <= std_logic_vector(framecounter);
-                                                               framecounter <= framecounter + 1;
-                                                               if mode = "01" then
-                                                                       if empty = '0' then
-                                                                               readout_fsm <= wait_memory;
-                                                                               rd_en       <= '1';
-                                                                       else
-                                                                               readout_fsm <= trailer;
-                                                                       end if;
-                                                               else
-                                                                       readout_fsm <= wait_trigger;
-                                                               end if;
-                                               end case;
-                                       when read_single =>
-                                               data_valid  <= '1';
-                                               busy        <= '1';
-                                               rd_en       <= '1';
-                                               data_out    <= data_in;
-                                               readout_fsm <= idle;
-                                       when wait_memory =>
-                                               busy <= '1';
-                                               if empty = '0' then
-                                                       readout_fsm <= read;
-                                                       rd_en       <= '1';
-                                               else
-                                                       readout_fsm <= trailer;
-                                                       rd_en       <= '0';
-                                               end if;
-                                       when read =>
-                                               busy        <= '1';
-                                               data_valid  <= '1';
-                                           data_out    <= data_in;
-                                           wordcounter <= wordcounter + 1;
-                                               readout_fsm <= read;
-                                               if mode = "01" then
-                                                       if wordcounter < unsigned(max_words) - 2 and almost_empty = '0' then
-                                                               rd_en       <= '1';
-                                                       else
-                                                               rd_en <= '0';
-                                                       end if;
-                                                       if almost_empty_edge = "01" or wordcounter = unsigned(max_words) - 1 then
-                                                               readout_fsm <= trailer;
-                                                       end if;
-                                               else
-                                                       if wordcounter < unsigned(max_words) - 2 and almost_empty = '0' then
-                                                               rd_en       <= '1';
-                                                       else
-                                                               rd_en       <= '0';
-                                                       end if;
-                                                       if almost_empty_edge = "01" or wordcounter = unsigned(max_words) - 1 then
-                                                               readout_fsm <= trailer;
-                                                       end if;
-                                               end if;
-                                       when wait_trigger =>
-                                               busy        <= '1';
-                                               offset_en   <= '0';
-                                               triggerwaitcounter <= triggerwaitcounter + 1;
-                                               if triggerwaitcounter = unsigned(writes_after_trig) - 1 then
-                                                       if empty = '0' then
-                                                               readout_fsm <= wait_memory;
-                                                               rd_en       <= '1';
-                                                       else
-                                                               readout_fsm <= trailer;
-                                                       end if; 
-                                               end if;
-                                               if triggerwaitcounter = unsigned(writes_after_trig) - 2 then
-                                                       offset_en   <= '1';
-                                               end if;
-                                       when trailer =>
-                                               busy           <= '1';
-                                               data_valid     <= '1';
-                                               readout_fsm    <= trailer;
-                                               trailercounter <= trailercounter + 1;
-                                               if trailercounter = 0 then
-                                                       data_out(g_addresswidth - 1 downto 0) <= std_logic_vector(wordcounter);
-                                               else
-                                                       data_out    <= c_frame_end;
-                                                       readout_fsm <= idle;
-                                               end if;
-                               end case;
-                       end if;
-               end if;
-       end process readout_proc;
+
+  readout_proc : process(clk) is
+  begin
+    if rising_edge(clk) then
+      if rst = '1' then
+        readout_fsm   <= idle;
+        rd_en         <= '0';
+        busy          <= '0';
+        data_valid    <= '0';
+        data_out      <= (others => '0');
+        framecounter  <= (others => '0');
+        headercounter <= 0;
+      else
+        busy       <= '0';
+        data_valid <= '0';
+        data_out   <= (others => '0');
+        rd_en      <= '0';
+        offset_en  <= '0';
+        case readout_fsm is
+          when idle =>
+            trailercounter     <= 0;
+            wordcounter        <= (others => '0');
+            headercounter      <= 0;
+            triggerwaitcounter <= (others => '0');
+            headercounter      <= 0;
+            if start = '1' then
+              busy <= '1';
+              if mode = "00" then
+                if empty = '0' then
+                  readout_fsm <= read_single;
+                else
+                  data_out    <= (others => '0');
+                  data_valid  <= '1';
+                  readout_fsm <= idle;
+                end if;
+              elsif mode = "01" then
+                readout_fsm <= header;
+              elsif mode = "10" then
+                readout_fsm <= header;
+              else
+                readout_fsm <= idle;
+              end if;
+            else
+              readout_fsm <= idle;
+            end if;
+          when header =>
+            busy          <= '1';
+            data_valid    <= '1';
+            headercounter <= headercounter + 1;
+            case headercounter is
+              when 0 =>
+                data_out <= c_frame_start;
+              when 1 =>
+                data_out <= sensor_id;
+              when 2 =>
+                data_out     <= std_logic_vector(framecounter);
+                framecounter <= framecounter + 1;
+                if mode = "01" then
+                  if empty = '0' then
+                    readout_fsm <= wait_memory;
+                    rd_en       <= '1';
+                  else
+                    readout_fsm <= trailer;
+                  end if;
+                else
+                  readout_fsm <= wait_trigger;
+                end if;
+            end case;
+          when read_single =>
+            data_valid  <= '1';
+            busy        <= '1';
+            rd_en       <= '1';
+            data_out    <= data_in;
+            readout_fsm <= idle;
+          when wait_memory =>
+            busy <= '1';
+            if empty = '0' then
+              readout_fsm <= read;
+              rd_en       <= '1';
+            else
+              readout_fsm <= trailer;
+              rd_en       <= '0';
+            end if;
+          when read =>
+            busy        <= '1';
+            data_valid  <= '1';
+            data_out    <= data_in;
+            wordcounter <= wordcounter + 1;
+            readout_fsm <= read;
+            if mode = "01" then
+              if wordcounter < unsigned(max_words) - 2 and almost_empty = '0' then
+                rd_en <= '1';
+              else
+                rd_en <= '0';
+              end if;
+              if almost_empty_edge = "01" or wordcounter = unsigned(max_words) - 1 then
+                readout_fsm <= trailer;
+              end if;
+            else
+              if wordcounter < unsigned(max_words) - 2 and almost_empty = '0' then
+                rd_en <= '1';
+              else
+                rd_en <= '0';
+              end if;
+              if almost_empty_edge = "01" or wordcounter = unsigned(max_words) - 1 then
+                readout_fsm <= trailer;
+              end if;
+            end if;
+          when wait_trigger =>
+            busy               <= '1';
+            offset_en          <= '0';
+            triggerwaitcounter <= triggerwaitcounter + 1;
+            if triggerwaitcounter = unsigned(writes_after_trig) - 1 then
+              if empty = '0' then
+                readout_fsm <= wait_memory;
+                rd_en       <= '1';
+              else
+                readout_fsm <= trailer;
+              end if;
+            end if;
+            if triggerwaitcounter = unsigned(writes_after_trig) - 2 then
+              offset_en <= '1';
+            end if;
+          when trailer =>
+            busy           <= '1';
+            data_valid     <= '1';
+            readout_fsm    <= trailer;
+            trailercounter <= trailercounter + 1;
+            if trailercounter = 0 then
+              data_out(g_addresswidth - 1 downto 0) <= std_logic_vector(wordcounter);
+            else
+              data_out    <= c_frame_end;
+              readout_fsm <= idle;
+            end if;
+        end case;
+      end if;
+    end if;
+  end process readout_proc;
 
 end architecture RTL;
index 23f99ed308ba83314e258ae302312ca84c376dc3..21175b82d4c27e63fcb109054c0c3adbda6ff5f4 100644 (file)
@@ -12,45 +12,45 @@ use ieee.numeric_std.all;
 
 entity TriggerHandler is
   port (
-    CLK_IN                     : in  std_logic;
-    RESET_IN                   : in  std_logic;
-    
+    CLK_IN   : in std_logic;
+    RESET_IN : in std_logic;
+
     --Input Triggers          
-    TIMING_TRIGGER_IN          : in std_logic; -- The raw timing Trigger Signal 
-    LVL1_TRG_DATA_VALID_IN     : in std_logic; -- Data Trigger is valid
-    LVL1_VALID_TIMING_TRG_IN   : in std_logic; -- Timin Trigger is valid
-    LVL1_VALID_NOTIMING_TRG_IN : in std_logic; -- calib trigger w/o ref time
-    LVL1_INVALID_TRG_IN        : in std_logic; 
-
-    LVL1_TRG_TYPE_IN           : in std_logic_vector(3 downto 0);
-    LVL1_TRG_NUMBER_IN         : in std_logic_vector(15 downto 0);
-    LVL1_TRG_CODE_IN           : in std_logic_vector(7 downto 0);
-  
+    TIMING_TRIGGER_IN          : in std_logic;  -- The raw timing Trigger Signal 
+    LVL1_TRG_DATA_VALID_IN     : in std_logic;  -- Data Trigger is valid
+    LVL1_VALID_TIMING_TRG_IN   : in std_logic;  -- Timin Trigger is valid
+    LVL1_VALID_NOTIMING_TRG_IN : in std_logic;  -- calib trigger w/o ref time
+    LVL1_INVALID_TRG_IN        : in std_logic;
+
+    LVL1_TRG_TYPE_IN   : in std_logic_vector(3 downto 0);
+    LVL1_TRG_NUMBER_IN : in std_logic_vector(15 downto 0);
+    LVL1_TRG_CODE_IN   : in std_logic_vector(7 downto 0);
+
     --Response from FEE
-    FEE_DATA_OUT               : out std_logic_vector(31 downto 0);
-    FEE_DATA_WRITE_OUT         : out std_logic;
-    FEE_DATA_FINISHED_OUT      : out std_logic;
-    FEE_TRG_RELEASE_OUT        : out std_logic;
-    FEE_TRG_STATUSBITS_OUT     : out std_logic_vector(31 downto 0);
-
-    FEE_DATA_0_IN              : in  std_logic_vector(31 downto 0);
-    FEE_DATA_WRITE_0_IN        : in  std_logic;
-    
+    FEE_DATA_OUT           : out std_logic_vector(31 downto 0);
+    FEE_DATA_WRITE_OUT     : out std_logic;
+    FEE_DATA_FINISHED_OUT  : out std_logic;
+    FEE_TRG_RELEASE_OUT    : out std_logic;
+    FEE_TRG_STATUSBITS_OUT : out std_logic_vector(31 downto 0);
+
+    FEE_DATA_0_IN       : in std_logic_vector(31 downto 0);
+    FEE_DATA_WRITE_0_IN : in std_logic;
+
     -- Trigger FeedBack
-    TRIGGER_BUSY_BUFFER_READ_IN   : in  std_logic;
-    
+    TRIGGER_BUSY_BUFFER_READ_IN : in std_logic;
+
     -- OUT
-    VALID_TRIGGER_OUT          : out std_logic;
-   
+    VALID_TRIGGER_OUT : out std_logic;
+
     -- Slave bus               
-    SLV_READ_IN                : in  std_logic;
-    SLV_WRITE_IN               : in  std_logic;
-    SLV_DATA_OUT               : out std_logic_vector(31 downto 0);
-    SLV_DATA_IN                : in  std_logic_vector(31 downto 0);
-    SLV_ADDR_IN                : in  std_logic_vector(15 downto 0);
-    SLV_ACK_OUT                : out std_logic;
-    SLV_NO_MORE_DATA_OUT       : out std_logic;
-    SLV_UNKNOWN_ADDR_OUT       : out std_logic);
+    SLV_READ_IN          : in  std_logic;
+    SLV_WRITE_IN         : in  std_logic;
+    SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
+    SLV_DATA_IN          : in  std_logic_vector(31 downto 0);
+    SLV_ADDR_IN          : in  std_logic_vector(15 downto 0);
+    SLV_ACK_OUT          : out std_logic;
+    SLV_NO_MORE_DATA_OUT : out std_logic;
+    SLV_UNKNOWN_ADDR_OUT : out std_logic);
 
 end entity TriggerHandler;
 
@@ -66,11 +66,11 @@ architecture behavioral of TriggerHandler is
   signal trigger_busy_int         : std_logic                     := '0';
   signal buffer_readout_end_int   : std_logic_vector(1 downto 0)  := "00";
 --fee
-  signal fee_data_int            : std_logic_vector(31 downto 0) := (others => '0');
-  signal fee_data_write_int      : std_logic                      := '0';
-  signal fee_data_finished_int   : std_logic                     := '0';
-  signal fee_trg_release_int     : std_logic                     := '0';
-  signal fee_trg_statusbit_int   : std_logic_vector(31 downto 0) := (others => '0');
+  signal fee_data_int             : std_logic_vector(31 downto 0) := (others => '0');
+  signal fee_data_write_int       : std_logic                     := '0';
+  signal fee_data_finished_int    : std_logic                     := '0';
+  signal fee_trg_release_int      : std_logic                     := '0';
+  signal fee_trg_statusbit_int    : std_logic_vector(31 downto 0) := (others => '0');
 --event buffer
 
 --registers
@@ -84,7 +84,7 @@ architecture behavioral of TriggerHandler is
   signal invalid_trigger_counter_t   : unsigned(31 downto 0)        := (others => '0');
   signal valid_trigger_counter_t     : unsigned(31 downto 0)        := (others => '0');
   signal trigger_handler_state       : std_logic_vector(7 downto 0) := (others => '0');
-  
+
 --trigger types
   constant c_trigger_physics_type : std_logic_vector(3 downto 0) := x"1";
   constant c_trigger_status_type  : std_logic_vector(3 downto 0) := x"e";
@@ -103,7 +103,7 @@ architecture behavioral of TriggerHandler is
                                 ignore,
                                 wait_trigger_data_valid_a,
                                 wait_trigger_data_valid_b);
-  
+
   type trigger_type_type is (t_timing,
                              t_physics,
                              t_status,
@@ -116,218 +116,227 @@ architecture behavioral of TriggerHandler is
   signal wr_data_int         : std_logic            := '0';
   signal wr_status_int       : std_logic            := '0';
   signal wr_dummy_int        : std_logic            := '0';
-  
+
 begin
-  
+
   Signal_Edge_Detect : process(CLK_IN) is
-       begin                               -- process Mupix_Readout_End_Detect
-               if rising_edge(CLK_IN) then
-                       if reset_in = '1' then
-                               buffer_readout_end_int   <= (others => '0');
-                               timing_trigger_edge      <= (others => '0');
-                               reset_trigger_state_edge <= (others => '0');
-                       else
-                               buffer_readout_end_int   <= buffer_readout_end_int(0) & TRIGGER_BUSY_BUFFER_READ_IN;
-                               timing_trigger_edge      <= timing_trigger_edge(0) & TIMING_TRIGGER_IN;
-                               reset_trigger_state_edge <= reset_trigger_state_edge(1) & reset_trigger_state;
-                       end if;
-               end if;
-       end process Signal_Edge_Detect;
-
-       ------------------------------------------------------------
-       --Handling of LVL1 triggers
-       ------------------------------------------------------------
-       trigger_handler_proc : process(clk_in) is
-       begin                               -- process trigger_handler_proc
-               if rising_edge(CLK_IN) then
-                       if reset_in = '1' or LVL1_INVALID_TRG_IN = '1' or reset_trigger_state_edge = "01" then
-                               valid_trigger_int     <= '0';
-                               fee_data_finished_int <= '0';
-                               fee_trg_release_int   <= '0';
-                               fee_trg_statusbit_int <= (others => '0');
-                               trigger_busy_int      <= '1';
-                               fee_trg_release_int   <= '0';
-                               wr_header_int         <= '0';
-                               wr_data_int           <= '0';
-                               wr_status_int         <= '0';
-                               wr_dummy_int          <= '0';
-                       else
-                               case trigger_handler_fsm is
-                                       when idle =>
-                                               trigger_busy_int      <= '0';
-                                               trigger_handler_state <= x"01";
-                                               if LVL1_VALID_TIMING_TRG_IN = '1' then
-                                                       wr_header_int <= '1';
-                                                       if bypass_trigger = '1' then
-                                                               trigger_type        <= t_ignore;
-                                                               trigger_handler_fsm <= ignore;
-                                                       else
-                                                               trigger_type        <= t_timing;
-                                                               trigger_handler_fsm <= timing_trigger;
-                                                       end if;
-                                               elsif (LVL1_VALID_NOTIMING_TRG_IN = '1') then
-                                                       wr_header_int <= '1';
-                                                       if bypass_trigger = '1' then
-                                                               trigger_type        <= t_ignore;
-                                                               trigger_handler_fsm <= ignore;
-                                                       else
-                                                               trigger_handler_fsm <= check_trigger_type;
-                                                       end if;
-                                               end if;
-
-                                       when check_trigger_type =>
-                                               trigger_handler_state <= x"02";
-                                               if (LVL1_TRG_DATA_VALID_IN = '1') then
-                                                       if (LVL1_TRG_TYPE_IN = c_trigger_status_type) then
-                                                               trigger_type        <= t_status;
-                                                               trigger_handler_fsm <= no_timing_trigger;
-                                                       elsif (LVL1_TRG_TYPE_IN = c_trigger_physics_type) then
-                                                               trigger_type        <= t_physics;
-                                                               trigger_handler_fsm <= no_timing_trigger;
-                                                       else
-                                                               --unknown trigger
-                                                               trigger_type        <= t_unknown;
-                                                               trigger_handler_fsm <= no_timing_trigger;
-                                                       end if;
-                                               else
-                                                       trigger_handler_fsm <= check_trigger_type;
-                                               end if;
-
-                                       when timing_trigger => --starts mupix readout fsm
-                                               trigger_handler_state <= x"03";
-                                               valid_trigger_int     <= '1';
-                                               trigger_handler_fsm   <= write_data_to_ipu;
-
-                                       when no_timing_trigger =>
-                                               trigger_handler_state <= x"04";
-                                               if trigger_type = t_physics then
-                                                       trigger_handler_fsm <= timing_trigger;
-                                               elsif trigger_type = t_status then
-                                                       trigger_handler_fsm <= status_trigger;
-                                               else
-                                                       trigger_handler_fsm <= ignore;
-                                               end if;
-
-                                       when ignore =>
-                                               wr_dummy_int          <= '1'; --write a dummy value to identify inactive FEE
-                                               trigger_handler_state <= x"05";
-                                               trigger_handler_fsm   <= wait_trigger_data_valid_b;
-
-                                       when status_trigger => --dummy implementation
-                                               trigger_handler_state <= x"06";
-                                               wr_status_int         <= '1';
-                                               trigger_handler_fsm   <= wait_trigger_data_valid_b;
-
-                                       when write_data_to_ipu =>
-                                               trigger_handler_state <= x"0A";
-                                               wr_data_int           <= '1';
-                                               if buffer_readout_end_int = "10" then
-                                                       wr_data_int         <= '0';
-                                                       trigger_handler_fsm <= wait_trigger_data_valid_a;
-                                               else
-                                                       trigger_handler_fsm <= write_data_to_ipu;
-                                               end if;
-
-                                       when wait_trigger_data_valid_a =>
-                                               trigger_handler_state <= x"0B";
-                                               if LVL1_TRG_DATA_VALID_IN = '1' then
-                                                       trigger_handler_fsm <= wait_trigger_data_valid_b;
-                                               end if;
-
-                                       when wait_trigger_data_valid_b =>
-                                               trigger_handler_state <= x"0C";
-                                               trigger_handler_fsm   <= trigger_release_a;
-
-                                       when trigger_release_a =>
-                                               trigger_handler_state <= x"0D";
-                                               trigger_handler_fsm   <= trigger_release_b;
-
-                                       when trigger_release_b =>
-                                               trigger_handler_state <= x"0E";
-                                               fee_data_finished_int <= '1';
-                                               trigger_handler_fsm   <= trigger_release_c;
-
-                                       when trigger_release_c =>
-                                               trigger_handler_state <= x"0F";
-                                               fee_trg_release_int   <= '1';
-                                               trigger_handler_fsm   <= wait_trigger_release;
-
-                                       when wait_trigger_release =>
-                                               if (LVL1_TRG_DATA_VALID_IN = '1') then
-                                                       trigger_handler_fsm <= wait_trigger_release;
-                                               else
-                                                       trigger_handler_fsm <= idle;
-                                               end if;
-                               end case;
-                       end if;
-               end if;
-       end process trigger_handler_proc;
+  begin  -- process Mupix_Readout_End_Detect
+    if rising_edge(CLK_IN) then
+      if reset_in = '1' then
+        buffer_readout_end_int   <= (others => '0');
+        timing_trigger_edge      <= (others => '0');
+        reset_trigger_state_edge <= (others => '0');
+      else
+        buffer_readout_end_int   <= buffer_readout_end_int(0) & TRIGGER_BUSY_BUFFER_READ_IN;
+        timing_trigger_edge      <= timing_trigger_edge(0) & TIMING_TRIGGER_IN;
+        reset_trigger_state_edge <= reset_trigger_state_edge(1) & reset_trigger_state;
+      end if;
+    end if;
+  end process Signal_Edge_Detect;
+
+  ------------------------------------------------------------
+  --Handling of LVL1 triggers
+  ------------------------------------------------------------
+  trigger_handler_proc : process(clk_in) is
+  begin  -- process trigger_handler_proc
+    if rising_edge(CLK_IN) then
+      trigger_busy_int        <= '1';
+      fee_trg_release_int     <= '0';
+      wr_header_int           <= '0';
+      wr_data_int             <= '0';
+      wr_status_int           <= '0';
+      wr_dummy_int            <= '0';
+      valid_trigger_int     <= '0';
+      fee_data_finished_int <= '0';
+      fee_trg_release_int   <= '0';
+      if reset_in = '1' or LVL1_INVALID_TRG_IN = '1' or reset_trigger_state_edge = "01" then
+        valid_trigger_int     <= '0';
+        fee_data_finished_int <= '0';
+        fee_trg_release_int   <= '0';
+        fee_trg_statusbit_int <= (others => '0');
+        trigger_busy_int      <= '1';
+        fee_trg_release_int   <= '0';
+        wr_header_int         <= '0';
+        wr_data_int           <= '0';
+        wr_status_int         <= '0';
+        wr_dummy_int          <= '0';
+      else
+        case trigger_handler_fsm is
+          when idle =>
+            trigger_busy_int      <= '0';
+            trigger_handler_state <= x"01";
+            if LVL1_VALID_TIMING_TRG_IN = '1' then
+              wr_header_int <= '1';
+              if bypass_trigger = '1' then
+                trigger_type        <= t_ignore;
+                trigger_handler_fsm <= ignore;
+              else
+                trigger_type        <= t_timing;
+                trigger_handler_fsm <= timing_trigger;
+              end if;
+            elsif (LVL1_VALID_NOTIMING_TRG_IN = '1') then
+              wr_header_int <= '1';
+              if bypass_trigger = '1' then
+                trigger_type        <= t_ignore;
+                trigger_handler_fsm <= ignore;
+              else
+                trigger_handler_fsm <= check_trigger_type;
+              end if;
+            end if;
+
+          when check_trigger_type =>
+            trigger_handler_state <= x"02";
+            if (LVL1_TRG_DATA_VALID_IN = '1') then
+              if (LVL1_TRG_TYPE_IN = c_trigger_status_type) then
+                trigger_type        <= t_status;
+                trigger_handler_fsm <= no_timing_trigger;
+              elsif (LVL1_TRG_TYPE_IN = c_trigger_physics_type) then
+                trigger_type        <= t_physics;
+                trigger_handler_fsm <= no_timing_trigger;
+              else
+                                        --unknown trigger
+                trigger_type        <= t_unknown;
+                trigger_handler_fsm <= no_timing_trigger;
+              end if;
+            else
+              trigger_handler_fsm <= check_trigger_type;
+            end if;
+
+          when timing_trigger =>        --starts mupix readout fsm
+            trigger_handler_state <= x"03";
+            valid_trigger_int     <= '1';
+            trigger_handler_fsm   <= write_data_to_ipu;
+
+          when no_timing_trigger =>
+            trigger_handler_state <= x"04";
+            if trigger_type = t_physics then
+              trigger_handler_fsm <= timing_trigger;
+            elsif trigger_type = t_status then
+              trigger_handler_fsm <= status_trigger;
+            else
+              trigger_handler_fsm <= ignore;
+            end if;
+
+          when ignore =>
+            wr_dummy_int          <= '1';  --write a dummy value to identify inactive FEE
+            trigger_handler_state <= x"05";
+            trigger_handler_fsm   <= wait_trigger_data_valid_b;
+
+          when status_trigger =>        --dummy implementation
+            trigger_handler_state <= x"06";
+            wr_status_int         <= '1';
+            trigger_handler_fsm   <= wait_trigger_data_valid_b;
+
+          when write_data_to_ipu =>
+            trigger_handler_state <= x"0A";
+            wr_data_int           <= '1';
+            if buffer_readout_end_int = "10" then
+              wr_data_int         <= '0';
+              trigger_handler_fsm <= wait_trigger_data_valid_a;
+            else
+              trigger_handler_fsm <= write_data_to_ipu;
+            end if;
+
+          when wait_trigger_data_valid_a =>
+            trigger_handler_state <= x"0B";
+            if LVL1_TRG_DATA_VALID_IN = '1' then
+              trigger_handler_fsm <= wait_trigger_data_valid_b;
+            end if;
+
+          when wait_trigger_data_valid_b =>
+            trigger_handler_state <= x"0C";
+            trigger_handler_fsm   <= trigger_release_a;
+
+          when trigger_release_a =>
+            trigger_handler_state <= x"0D";
+            trigger_handler_fsm   <= trigger_release_b;
+
+          when trigger_release_b =>
+            trigger_handler_state <= x"0E";
+            fee_data_finished_int <= '1';
+            trigger_handler_fsm   <= trigger_release_c;
+
+          when trigger_release_c =>
+            trigger_handler_state <= x"0F";
+            fee_trg_release_int   <= '1';
+            trigger_handler_fsm   <= wait_trigger_release;
+
+          when wait_trigger_release =>
+            if (LVL1_TRG_DATA_VALID_IN = '1') then
+              trigger_handler_fsm <= wait_trigger_release;
+            else
+              trigger_handler_fsm <= idle;
+            end if;
+        end case;
+      end if;
+    end if;
+  end process trigger_handler_proc;
 
   ------------------------------------------------------------
   --Data Output Mux
   ------------------------------------------------------------
   Data_Out_Mux : process(clk_in) is
-       begin                               -- process Data_Out_Mux
-               if rising_edge(clk_in) then
-                       if Reset_in = '1' then
-                               fee_data_write_int <= '0';
-                               fee_data_int       <= (others => '0');
-                       else
-                               if wr_header_int = '1' then
-                                       fee_data_write_int <= '1'; --header see Hades DAQ user guide
-                                       fee_data_int       <= "001" & "0" & LVL1_TRG_TYPE_IN & LVL1_TRG_CODE_IN & LVL1_TRG_NUMBER_IN;
-                               elsif wr_data_int = '1' then
-                                       fee_data_write_int <= FEE_DATA_WRITE_0_IN;
-                                       fee_data_int       <= FEE_DATA_0_IN;
-                               elsif wr_status_int = '1' then
-                                       fee_data_int       <= x"deadbeef";
-                                       fee_data_write_int <= '1';
-                               elsif wr_dummy_int = '1' then
-                                       fee_data_write_int <= '1';
-                                       fee_data_int       <= x"fff00000";
-                               else
-                                       fee_data_write_int <= '0';
-                                       fee_data_int       <= (others => '1');
-                               end if;
-                       end if;
-               end if;
-       end process Data_Out_Mux;
-
-  
+  begin  -- process Data_Out_Mux
+    if rising_edge(clk_in) then
+      if Reset_in = '1' then
+        fee_data_write_int <= '0';
+        fee_data_int       <= (others => '0');
+      else
+        if wr_header_int = '1' then
+          fee_data_write_int <= '1';    --header see Hades DAQ user guide
+          fee_data_int       <= "001" & "0" & LVL1_TRG_TYPE_IN & LVL1_TRG_CODE_IN & LVL1_TRG_NUMBER_IN;
+        elsif wr_data_int = '1' then
+          fee_data_write_int <= FEE_DATA_WRITE_0_IN;
+          fee_data_int       <= FEE_DATA_0_IN;
+        elsif wr_status_int = '1' then
+          fee_data_int       <= x"deadbeef";
+          fee_data_write_int <= '1';
+        elsif wr_dummy_int = '1' then
+          fee_data_write_int <= '1';
+          fee_data_int       <= x"ffeeddcc";
+        else
+          fee_data_write_int <= '0';
+          fee_data_int       <= (others => '1');
+        end if;
+      end if;
+    end if;
+  end process Data_Out_Mux;
+
+
   ------------------------------------------------------------
-       --Trigger statistics
-       ------------------------------------------------------------
-       Trigger_Statistics_Proc : process(clk_in) is
-       begin                               -- process Trigger_Statistics_Proc
-               if rising_edge(CLK_IN) then
-                       reset_trigger_counters_edge <= reset_trigger_counters_edge(0) & reset_trigger_counters;
-                       if reset_trigger_counters_edge = "01" or RESET_IN = '1' then
-                               trigger_rate_acc          <= (others => '0');
-                               invalid_trigger_counter_t <= (others => '0');
-                               valid_trigger_counter_t   <= (others => '0');
-                               trigger_rate_time_counter <= (others => '0');
-                       else
-                               if trigger_rate_time_counter < x"5f5e100" then --1s at 10ns clock period
-                                       --if trigger_rate_time_counter < x"000007e" then
-                                       trigger_rate_time_counter <= trigger_rate_time_counter + 1;
-                                       if valid_trigger_int = '1' then
-                                               valid_trigger_counter_t <= valid_trigger_counter_t + 1;
-                                       elsif LVL1_INVALID_TRG_IN = '1' or (trigger_busy_int = '1' and timing_trigger_edge = "01") then
-                                               invalid_trigger_counter_t <= invalid_trigger_counter_t + 1;
-                                       end if;
-                               else
-                                       valid_trigger_counter     <= valid_trigger_counter + valid_trigger_counter_t;
-                                       invalid_trigger_counter   <= invalid_trigger_counter + invalid_trigger_counter_t;
-                                       trigger_rate_acc          <= valid_trigger_counter_t;
-                                       trigger_rate_tot          <= valid_trigger_counter_t + invalid_trigger_counter_t;
-                                       trigger_rate_time_counter <= (others => '0');
-                                       valid_trigger_counter_t   <= (others => '0');
-                                       invalid_trigger_counter_t <= (others => '0');
-                               end if;
-                       end if;
-               end if;
-       end process Trigger_Statistics_Proc;
-  
+  --Trigger statistics
+  ------------------------------------------------------------
+  Trigger_Statistics_Proc : process(clk_in) is
+  begin  -- process Trigger_Statistics_Proc
+    if rising_edge(CLK_IN) then
+      reset_trigger_counters_edge <= reset_trigger_counters_edge(0) & reset_trigger_counters;
+      if reset_trigger_counters_edge = "01" or RESET_IN = '1' then
+        trigger_rate_acc          <= (others => '0');
+        invalid_trigger_counter_t <= (others => '0');
+        valid_trigger_counter_t   <= (others => '0');
+        trigger_rate_time_counter <= (others => '0');
+      else
+        if trigger_rate_time_counter < x"5f5e100" then  --1s at 10ns clock period
+                                                        --if trigger_rate_time_counter < x"000007e" then
+          trigger_rate_time_counter <= trigger_rate_time_counter + 1;
+          if valid_trigger_int = '1' then
+            valid_trigger_counter_t <= valid_trigger_counter_t + 1;
+          elsif LVL1_INVALID_TRG_IN = '1' or (trigger_busy_int = '1' and timing_trigger_edge = "01") then
+            invalid_trigger_counter_t <= invalid_trigger_counter_t + 1;
+          end if;
+        else
+          valid_trigger_counter     <= valid_trigger_counter + valid_trigger_counter_t;
+          invalid_trigger_counter   <= invalid_trigger_counter + invalid_trigger_counter_t;
+          trigger_rate_acc          <= valid_trigger_counter_t;
+          trigger_rate_tot          <= valid_trigger_counter_t + invalid_trigger_counter_t;
+          trigger_rate_time_counter <= (others => '0');
+          valid_trigger_counter_t   <= (others => '0');
+          invalid_trigger_counter_t <= (others => '0');
+        end if;
+      end if;
+    end if;
+  end process Trigger_Statistics_Proc;
+
   ------------------------------------------------------------
   --TRB SLV-BUS Hanlder
   ------------------------------------------------------------
@@ -339,63 +348,63 @@ begin
   --0x125: reset counters
   --0x126: reset trigger state machine
   --0x127: bypass trigger signals flag
-       slv_bus_handler : process(CLK_IN)
-       begin
-               if rising_edge(CLK_IN) then
-
-                       slv_data_out         <= (others => '0');
-                       slv_ack_out          <= '0';
-                       slv_no_more_data_out <= '0';
-                       slv_unknown_addr_out <= '0';
-
-                       if slv_write_in = '1' then
-                               case SLV_ADDR_IN is
-                                       when x"0125" =>
-                                               reset_trigger_counters <= SLV_DATA_IN(0);
-                                               slv_ack_out            <= '1';
-                                       when x"0126" =>
-                                               reset_trigger_state <= SLV_DATA_IN(0);
-                                               slv_ack_out         <= '1';
-                                       when x"0127" =>
-                                               bypass_trigger <= SLV_DATA_IN(0);
-                                               slv_ack_out    <= '1';
-                                       when others =>
-                                               slv_unknown_addr_out <= '1';
-                               end case;
-
-                       elsif slv_read_in = '1' then
-                               case slv_addr_in is
-                                       when x"0120" =>
-                                               slv_data_out <= std_logic_vector(trigger_rate_acc);
-                                               slv_ack_out  <= '1';
-                                       when x"0121" =>
-                                               slv_data_out <= std_logic_vector(trigger_rate_tot);
-                                               slv_ack_out  <= '1';
-                                       when x"0122" =>
-                                               slv_data_out <= std_logic_vector(invalid_trigger_counter);
-                                               slv_ack_out  <= '1';
-                                       when x"0123" =>
-                                               slv_data_out <= std_logic_vector(valid_trigger_counter);
-                                               slv_ack_out  <= '1';
-                                       when x"0124" =>
-                                               slv_data_out <= x"000000" & trigger_handler_state;
-                                               slv_ack_out  <= '1';
-                                       when x"0127" =>
-                                               slv_data_out(0) <= bypass_trigger;
-                                               slv_ack_out     <= '1';
-                                       when others =>
-                                               slv_unknown_addr_out <= '1';
-                               end case;
-                       end if;
-               end if;
-       end process slv_bus_handler;
+  slv_bus_handler : process(CLK_IN)
+  begin
+    if rising_edge(CLK_IN) then
+
+      slv_data_out         <= (others => '0');
+      slv_ack_out          <= '0';
+      slv_no_more_data_out <= '0';
+      slv_unknown_addr_out <= '0';
+
+      if slv_write_in = '1' then
+        case SLV_ADDR_IN is
+          when x"0125" =>
+            reset_trigger_counters <= SLV_DATA_IN(0);
+            slv_ack_out            <= '1';
+          when x"0126" =>
+            reset_trigger_state <= SLV_DATA_IN(0);
+            slv_ack_out         <= '1';
+          when x"0127" =>
+            bypass_trigger <= SLV_DATA_IN(0);
+            slv_ack_out    <= '1';
+          when others =>
+            slv_unknown_addr_out <= '1';
+        end case;
+
+      elsif slv_read_in = '1' then
+        case slv_addr_in is
+          when x"0120" =>
+            slv_data_out <= std_logic_vector(trigger_rate_acc);
+            slv_ack_out  <= '1';
+          when x"0121" =>
+            slv_data_out <= std_logic_vector(trigger_rate_tot);
+            slv_ack_out  <= '1';
+          when x"0122" =>
+            slv_data_out <= std_logic_vector(invalid_trigger_counter);
+            slv_ack_out  <= '1';
+          when x"0123" =>
+            slv_data_out <= std_logic_vector(valid_trigger_counter);
+            slv_ack_out  <= '1';
+          when x"0124" =>
+            slv_data_out <= x"000000" & trigger_handler_state;
+            slv_ack_out  <= '1';
+          when x"0127" =>
+            slv_data_out(0) <= bypass_trigger;
+            slv_ack_out     <= '1';
+          when others =>
+            slv_unknown_addr_out <= '1';
+        end case;
+      end if;
+    end if;
+  end process slv_bus_handler;
 
   --map output signals
-  valid_trigger_out     <= valid_trigger_int;
-  fee_data_out          <= fee_data_int;
-  fee_data_write_out    <= fee_data_write_int;
-  fee_data_finished_out <= fee_data_finished_int;
-  fee_trg_release_out   <= fee_trg_release_int;
+  valid_trigger_out      <= valid_trigger_int;
+  fee_data_out           <= fee_data_int;
+  fee_data_write_out     <= fee_data_write_int;
+  fee_data_finished_out  <= fee_data_finished_int;
+  fee_trg_release_out    <= fee_trg_release_int;
   fee_trg_statusbits_out <= fee_trg_statusbit_int;
 
 end architecture behavioral;
diff --git a/mupix/Mupix8/tb/MupixTRBReadoutAndTriggerTest.vhd b/mupix/Mupix8/tb/MupixTRBReadoutAndTriggerTest.vhd
new file mode 100644 (file)
index 0000000..2bfbaa6
--- /dev/null
@@ -0,0 +1,392 @@
+--Test bench for combined trigger and mupix trb readout
+--note that some code for the slow control is omitted and not all signals will
+--work as expected
+--T. Weber
+--Ruhr Universität Bochum
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.numeric_std.all;
+
+entity TriggerAndReadout is
+  port (
+    clk   : in std_logic;
+    reset : in std_logic;
+
+    --trigger signals
+    timing_trg_in              : in std_logic;
+    lvl1_trg_data_valid_in     : in std_logic;
+    lvl1_valid_timing_trg_in   : in std_logic;
+    lvl1_valid_notiming_trg_in : in std_logic;
+    lvl1_invalid_trg_in        : in std_logic;
+    lvl1_trg_type_in           : in std_logic_vector(3 downto 0);
+    lvl1_trg_number_in         : in std_logic_vector(15 downto 0);
+    lvl1_trg_code_in           : in std_logic_vector(7 downto 0);
+    lvl1_trg_information_in    : in std_logic_vector(23 downto 0);
+    lvl1_int_trg_number_in     : in std_logic_vector(15 downto 0);
+
+    --TRB data connections
+    fee_trg_release_out     : out std_logic;
+    fee_trg_statusbits_out  : out std_logic_vector(31 downto 0);
+    fee_data_out            : out std_logic_vector(31 downto 0);
+    fee_data_write_out      : out std_logic;
+    fee_data_finished_out   : out std_logic;
+    fee_data_almost_full_in : in  std_logic;
+
+    --Slow Control signals (slightly simplified)
+    slv_addr_in          : in  std_logic_vector(15 downto 0);
+    slv_data_in          : in  std_logic_vector(31 downto 0);
+    slv_data_out         : out std_logic_vector(31 downto 0);
+    slv_read_enable_in   : in  std_logic;
+    slv_write_enable_in  : in  std_logic;
+    slv_ack_out          : out std_logic;
+    slv_no_more_data_out : out std_logic;
+    slv_unknown_addr_out : out std_logic;
+
+    --Pseudo Data Inputs
+    data_wr_enable : in std_logic_vector(3 downto 0);
+    data_in        : in std_logic_vector(127 downto 0));
+end entity TriggerAndReadout;
+
+
+architecture behavorial of TriggerAndReadout is
+
+  component TriggerHandler is
+    port (
+      CLK_IN                      : in  std_logic;
+      RESET_IN                    : in  std_logic;
+      TIMING_TRIGGER_IN           : in  std_logic;
+      LVL1_TRG_DATA_VALID_IN      : in  std_logic;
+      LVL1_VALID_TIMING_TRG_IN    : in  std_logic;
+      LVL1_VALID_NOTIMING_TRG_IN  : in  std_logic;
+      LVL1_INVALID_TRG_IN         : in  std_logic;
+      LVL1_TRG_TYPE_IN            : in  std_logic_vector(3 downto 0);
+      LVL1_TRG_NUMBER_IN          : in  std_logic_vector(15 downto 0);
+      LVL1_TRG_CODE_IN            : in  std_logic_vector(7 downto 0);
+      FEE_DATA_OUT                : out std_logic_vector(31 downto 0);
+      FEE_DATA_WRITE_OUT          : out std_logic;
+      FEE_DATA_FINISHED_OUT       : out std_logic;
+      FEE_TRG_RELEASE_OUT         : out std_logic;
+      FEE_TRG_STATUSBITS_OUT      : out std_logic_vector(31 downto 0);
+      FEE_DATA_0_IN               : in  std_logic_vector(31 downto 0);
+      FEE_DATA_WRITE_0_IN         : in  std_logic;
+      TRIGGER_BUSY_BUFFER_READ_IN : in  std_logic;
+      VALID_TRIGGER_OUT           : out std_logic;
+      SLV_READ_IN                 : in  std_logic;
+      SLV_WRITE_IN                : in  std_logic;
+      SLV_DATA_OUT                : out std_logic_vector(31 downto 0);
+      SLV_DATA_IN                 : in  std_logic_vector(31 downto 0);
+      SLV_ADDR_IN                 : in  std_logic_vector(15 downto 0);
+      SLV_ACK_OUT                 : out std_logic;
+      SLV_NO_MORE_DATA_OUT        : out std_logic;
+      SLV_UNKNOWN_ADDR_OUT        : out std_logic);
+  end component TriggerHandler;
+
+  component MupixTRBReadout is
+    generic (
+      g_mupix_links           : natural;
+      g_cyc_mem_address_width : integer;
+      g_datawidth             : integer);
+    port (
+      clk                  : in  std_logic;
+      rst                  : in  std_logic;
+      fifo_empty           : in  std_logic_vector(g_mupix_links - 1 downto 0);
+      fifo_full            : in  std_logic_vector(g_mupix_links - 1 downto 0);
+      fifo_datain          : in  std_logic_vector(g_mupix_links*g_datawidth - 1 downto 0);
+      fifo_rden            : out std_logic_vector(g_mupix_links - 1 downto 0);
+      trb_trigger          : in  std_logic;
+      dataout              : out std_logic_vector(g_datawidth - 1 downto 0);
+      data_valid           : out std_logic;
+      busy                 : out std_logic;
+      SLV_READ_IN          : in  std_logic;
+      SLV_WRITE_IN         : in  std_logic;
+      SLV_DATA_OUT         : out std_logic_vector(31 downto 0);
+      SLV_DATA_IN          : in  std_logic_vector(31 downto 0);
+      SLV_ADDR_IN          : in  std_logic_vector(15 downto 0);
+      SLV_ACK_OUT          : out std_logic;
+      SLV_NO_MORE_DATA_OUT : out std_logic;
+      SLV_UNKNOWN_ADDR_OUT : out std_logic);
+  end component MupixTRBReadout;
+
+  component STD_FIFO is
+    generic (
+      data_width : positive;
+      fifo_depth : positive);
+    port (
+      clk     : in  std_logic;
+      rst     : in  std_logic;
+      writeen : in  std_logic;
+      datain  : in  std_logic_vector (data_width - 1 downto 0);
+      readen  : in  std_logic;
+      dataout : out std_logic_vector (data_width - 1 downto 0);
+      empty   : out std_logic;
+      full    : out std_logic);
+  end component STD_FIFO;
+
+  constant c_mupix_links : integer := 4;
+
+  -- signals between trigger and and TRB Readout
+  signal fee_data_i            : std_logic_vector(31 downto 0);
+  signal fee_data_write_i      : std_logic;
+  signal trigger_buffer_busy_i : std_logic;
+  signal valid_trigger_i       : std_logic;
+
+  -- signals between FIFOs and TRB Readout
+  signal fifo_full_i    : std_logic_vector(c_mupix_links - 1 downto 0);
+  signal fifo_empty_i   : std_logic_vector(c_mupix_links - 1 downto 0);
+  signal fifo_rden_i    : std_logic_vector(c_mupix_links - 1 downto 0);
+  signal fifo_dataout_i : std_logic_vector(c_mupix_links*32 - 1 downto 0);
+
+begin  -- architecture behavorial 
+
+  TriggerHandler_1 : entity work.TriggerHandler
+    port map (
+      clk_in                      => clk,
+      reset_in                    => reset,
+      timing_trigger_in           => timing_trg_in,
+      lvl1_trg_data_valid_in      => lvl1_trg_data_valid_in,
+      lvl1_valid_timing_trg_in    => lvl1_valid_timing_trg_in,
+      lvl1_valid_notiming_trg_in  => lvl1_valid_notiming_trg_in,
+      lvl1_invalid_trg_in         => lvl1_invalid_trg_in,
+      lvl1_trg_type_in            => lvl1_trg_type_in,
+      lvl1_trg_number_in          => lvl1_trg_number_in,
+      lvl1_trg_code_in            => lvl1_trg_code_in,
+      fee_data_out                => fee_data_out,
+      fee_data_write_out          => fee_data_write_out,
+      fee_data_finished_out       => fee_data_finished_out,
+      fee_trg_release_out         => fee_trg_release_out,
+      fee_trg_statusbits_out      => fee_trg_statusbits_out,
+      fee_data_0_in               => fee_data_i,
+      fee_data_write_0_in         => fee_data_write_i,
+      trigger_busy_buffer_read_in => trigger_buffer_busy_i,
+      valid_trigger_out           => valid_trigger_i,
+      slv_read_in                 => slv_read_enable_in,
+      slv_write_in                => slv_write_enable_in,
+      slv_data_out                => slv_data_out,
+      slv_data_in                 => slv_data_in,
+      slv_addr_in                 => slv_addr_in,
+      slv_ack_out                 => slv_ack_out,
+      slv_no_more_data_out        => slv_no_more_data_out,
+      slv_unknown_addr_out        => slv_unknown_addr_out);
+
+  MupixTRBReadout_1 : entity work.MupixTRBReadout
+    generic map (
+      g_mupix_links           => c_mupix_links,
+      g_cyc_mem_address_width => 8,
+      g_datawidth             => 32)
+    port map (
+      clk                  => clk,
+      rst                  => reset,
+      fifo_empty           => fifo_empty_i,
+      fifo_full            => fifo_full_i,
+      fifo_datain          => fifo_dataout_i,
+      fifo_rden            => fifo_rden_i,
+      trb_trigger          => valid_trigger_i,
+      dataout              => fee_data_i,
+      data_valid           => fee_data_write_i,
+      busy                 => trigger_buffer_busy_i,
+      slv_read_in          => slv_read_enable_in,
+      slv_write_in         => slv_write_enable_in,
+      slv_data_out         => slv_data_out,
+      slv_data_in          => slv_data_in,
+      slv_addr_in          => slv_addr_in,
+      slv_ack_out          => slv_ack_out,
+      slv_no_more_data_out => slv_no_more_data_out,
+      slv_unknown_addr_out => slv_unknown_addr_out);
+
+  fifo_gen : for J in 0 to 3 generate
+    STD_FIFO : entity work.STD_FIFO
+      generic map (
+        data_width => 32,
+        fifo_depth => 16)
+      port map (
+        clk     => clk,
+        rst     => reset,
+        writeen => data_wr_enable(J),
+        datain  => data_in((J + 1)*32 - 1 downto J*32),
+        readen  => fifo_rden_i(J),
+        dataout => fifo_dataout_i((J + 1)*32 - 1 downto J*32),
+        empty   => fifo_empty_i(J),
+        full    => fifo_full_i(J));
+  end generate fifo_gen;
+
+end architecture behavorial;
+
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.all;
+use IEEE.numeric_std.all;
+
+entity ReadoutAndTriggerTest is
+end entity ReadoutAndTriggerTest;
+
+
+architecture sim of ReadoutAndTriggerTest is
+
+  component TriggerAndReadout is
+    port (
+      clk                        : in  std_logic;
+      reset                      : in  std_logic;
+      timing_trg_in              : in  std_logic;
+      lvl1_trg_data_valid_in     : in  std_logic;
+      lvl1_valid_timing_trg_in   : in  std_logic;
+      lvl1_valid_notiming_trg_in : in  std_logic;
+      lvl1_invalid_trg_in        : in  std_logic;
+      lvl1_trg_type_in           : in  std_logic_vector(3 downto 0);
+      lvl1_trg_number_in         : in  std_logic_vector(15 downto 0);
+      lvl1_trg_code_in           : in  std_logic_vector(7 downto 0);
+      lvl1_trg_information_in    : in  std_logic_vector(23 downto 0);
+      lvl1_int_trg_number_in     : in  std_logic_vector(15 downto 0);
+      fee_trg_release_out        : out std_logic;
+      fee_trg_statusbits_out     : out std_logic_vector(31 downto 0);
+      fee_data_out               : out std_logic_vector(31 downto 0);
+      fee_data_write_out         : out std_logic;
+      fee_data_finished_out      : out std_logic;
+      fee_data_almost_full_in    : in  std_logic;
+      slv_addr_in                : in  std_logic_vector(15 downto 0);
+      slv_data_in                : in  std_logic_vector(31 downto 0);
+      slv_data_out               : out std_logic_vector(31 downto 0);
+      slv_read_enable_in         : in  std_logic;
+      slv_write_enable_in        : in  std_logic;
+      slv_ack_out                : out std_logic;
+      slv_no_more_data_out       : out std_logic;
+      slv_unknown_addr_out       : out std_logic;
+      data_wr_enable             : in  std_logic_vector(3 downto 0);
+      data_in                    : in  std_logic_vector(127 downto 0));
+  end component TriggerAndReadout;
+
+  constant clk_period : time := 10 ns;
+
+  signal clk                        : std_logic                      := '0';
+  signal reset                      : std_logic                      := '0';
+  signal timing_trg_in              : std_logic                      := '0';
+  signal lvl1_trg_data_valid_in     : std_logic                      := '0';
+  signal lvl1_valid_timing_trg_in   : std_logic                      := '0';
+  signal lvl1_valid_notiming_trg_in : std_logic                      := '0';
+  signal lvl1_invalid_trg_in        : std_logic                      := '0';
+  signal lvl1_trg_type_in           : std_logic_vector(3 downto 0)   := (others => '0');
+  signal lvl1_trg_number_in         : std_logic_vector(15 downto 0)  := (others => '0');
+  signal lvl1_trg_code_in           : std_logic_vector(7 downto 0)   := (others => '0');
+  signal lvl1_trg_information_in    : std_logic_vector(23 downto 0)  := (others => '0');
+  signal lvl1_int_trg_number_in     : std_logic_vector(15 downto 0)  := (others => '0');
+  signal fee_trg_release_out        : std_logic;
+  signal fee_trg_statusbits_out     : std_logic_vector(31 downto 0);
+  signal fee_data_out               : std_logic_vector(31 downto 0);
+  signal fee_data_write_out         : std_logic;
+  signal fee_data_finished_out      : std_logic;
+  signal fee_data_almost_full_in    : std_logic                      := '0';
+  signal slv_addr_in                : std_logic_vector(15 downto 0)  := (others => '0');
+  signal slv_data_in                : std_logic_vector(31 downto 0)  := (others => '0');
+  signal slv_data_out               : std_logic_vector(31 downto 0)  := (others => '0');
+  signal slv_read_enable_in         : std_logic                      := '0';
+  signal slv_write_enable_in        : std_logic                      := '0';
+  signal slv_ack_out                : std_logic;
+  signal slv_no_more_data_out       : std_logic;
+  signal slv_unknown_addr_out       : std_logic;
+  signal data_wr_enable             : std_logic_vector(3 downto 0)   := (others => '0');
+  signal data_in                    : std_logic_vector(127 downto 0) := (others => '0');
+
+begin  -- architecture sim
+
+  TriggerAndReadout_1 : entity work.TriggerAndReadout
+    port map (
+      clk                        => clk,
+      reset                      => reset,
+      timing_trg_in              => timing_trg_in,
+      lvl1_trg_data_valid_in     => lvl1_trg_data_valid_in,
+      lvl1_valid_timing_trg_in   => lvl1_valid_timing_trg_in,
+      lvl1_valid_notiming_trg_in => lvl1_valid_notiming_trg_in,
+      lvl1_invalid_trg_in        => lvl1_invalid_trg_in,
+      lvl1_trg_type_in           => lvl1_trg_type_in,
+      lvl1_trg_number_in         => lvl1_trg_number_in,
+      lvl1_trg_code_in           => lvl1_trg_code_in,
+      lvl1_trg_information_in    => lvl1_trg_information_in,
+      lvl1_int_trg_number_in     => lvl1_int_trg_number_in,
+      fee_trg_release_out        => fee_trg_release_out,
+      fee_trg_statusbits_out     => fee_trg_statusbits_out,
+      fee_data_out               => fee_data_out,
+      fee_data_write_out         => fee_data_write_out,
+      fee_data_finished_out      => fee_data_finished_out,
+      fee_data_almost_full_in    => fee_data_almost_full_in,
+      slv_addr_in                => slv_addr_in,
+      slv_data_in                => slv_data_in,
+      slv_data_out               => slv_data_out,
+      slv_read_enable_in         => slv_read_enable_in,
+      slv_write_enable_in        => slv_write_enable_in,
+      slv_ack_out                => slv_ack_out,
+      slv_no_more_data_out       => slv_no_more_data_out,
+      slv_unknown_addr_out       => slv_unknown_addr_out,
+      data_wr_enable             => data_wr_enable,
+      data_in                    => data_in);
+
+  clk_gen : process is
+  begin  -- process clk_gen
+    clk <= '1';
+    wait for clk_period/2;
+    clk <= '0';
+    wait for clk_period/2;
+  end process clk_gen;
+
+  stimulus : process is
+  begin  -- process stimulus
+    -- test of trigger bypass
+    wait for 100 ns;
+    lvl1_valid_timing_trg_in   <= '1';
+    wait for 2*clk_period;
+    lvl1_valid_timing_trg_in   <= '0';
+    -- deactivate trigger bypass and simulate no timing triggers
+    wait for 100 ns;
+    slv_write_enable_in        <= '1';
+    slv_addr_in                <= x"0127";
+    slv_data_in                <= (others => '0');
+    wait for clk_period;
+    slv_write_enable_in        <= '0';
+    slv_addr_in                <= (others => '0');
+    -- status trigger
+    lvl1_valid_notiming_trg_in <= '1';
+    lvl1_trg_data_valid_in     <= '1';
+    lvl1_trg_type_in           <= x"e";
+    wait for 10*clk_period;
+    lvl1_valid_notiming_trg_in <= '0';
+    lvl1_trg_data_valid_in     <= '0';
+    lvl1_trg_type_in           <= (others => '0');
+    wait for 100 ns;
+    -- configure the readout controller
+    slv_write_enable_in        <= '1';
+    slv_addr_in                <= x"0100";
+    slv_data_in                <= x"00000001";
+    wait for clk_period;
+    slv_write_enable_in        <= '1';
+    slv_addr_in                <= x"0102";
+    slv_data_in                <= x"0000000a";
+    wait for clk_period;
+    slv_write_enable_in        <= '1';
+    slv_addr_in                <= x"0103";
+    slv_data_in                <= x"caadcaad";
+    wait for clk_period;
+    slv_write_enable_in        <= '1';
+    slv_addr_in                <= x"0105";
+    slv_data_in                <= x"0000000f";
+    wait for clk_period;
+    slv_write_enable_in        <= '0';
+    -- fill some data into the fifos
+    for i in 0 to 10 loop
+      data_wr_enable <= (others => '1');
+      for J in 0 to 3 loop
+        data_in((J + 1)*32 - 1 downto J*32) <= x"CA" & std_logic_vector(to_unsigned(J, 8)) & std_logic_vector(to_unsigned(i, 16));
+      end loop;  -- J
+      wait for clk_period;
+    end loop;  -- i
+    -- physics trigger
+    lvl1_valid_notiming_trg_in <= '1';
+    lvl1_trg_data_valid_in     <= '1';
+    lvl1_trg_type_in           <= x"1";
+    wait for 40*clk_period;
+    lvl1_valid_notiming_trg_in <= '0';
+    lvl1_trg_data_valid_in     <= '0';
+    lvl1_trg_type_in           <= (others => '0');
+    
+    wait;
+  end process stimulus;
+
+end architecture sim;