--- /dev/null
+----------------------------------------------------------------------
+-- Data Filter to seperate mupix hits from counter information
+-- It makes use of the redundancy of the column and link information
+-- to reduce the data width from 40 to 32 bit
+-- T. Weber, Ruhr University Bochum
+---------------------------------------------------------------------
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity MupixDataFilter is
+ port(
+ clk : in std_logic; -- clock input
+ reset : in std_logic; -- reset input
+ datain : in std_logic_vector(39 downto 0); -- data in
+ datain_valid : in std_logic; -- data in valid signal
+ dataout : out std_logic_vector(31 downto 0); -- data out
+ dataout_valid : out std_logic; -- data out valid signal
+ counterA : out std_logic_vector(31 downto 0); -- last counter value link A
+ counterB : out std_logic_vector(31 downto 0); -- last counter value link B
+ counterC : out std_logic_vector(31 downto 0); -- last counter value link C
+ counterD : out std_logic_vector(31 downto 0) -- last counter value link D
+ );
+end entity MupixDataFilter;
+
+
+architecture RTL of MupixDataFilter is
+
+ signal dataout_i : std_logic_vector(31 downto 0) := (others => '0');
+ signal dataout_valid_i : std_logic := '0';
+ signal counterA_i : std_logic_vector(31 downto 0) := (others => '0');
+ signal counterB_i : std_logic_vector(31 downto 0) := (others => '0');
+ signal counterC_i : std_logic_vector(31 downto 0) := (others => '0');
+ signal counterD_i : std_logic_vector(31 downto 0) := (others => '0');
+
+begin
+
+ filter_proc : process(clk)
+ begin
+ if rising_edge(clk) then
+ if reset = '1' then
+ dataout_i <= (others => '0');
+ counterA_i <= (others => '0');
+ counterB_i <= (others => '0');
+ counterC_i <= (others => '0');
+ counterD_i <= (others => '0');
+ dataout_valid_i <= '0';
+ else
+ dataout_valid_i <= '0';
+ dataout_i <= (others => '0');
+ if datain_valid = '1' then
+ if datain(39 downto 36) = x"3" then -- counter
+ case datain(35 downto 32) is
+ when x"A" =>
+ counterA_i <= datain(31 downto 0);
+ when x"B" =>
+ counterB_i <= datain(31 downto 0);
+ when x"C" =>
+ counterC_i <= datain(31 downto 0);
+ when others => null;
+ end case;
+ else -- hit
+ if datain(39 downto 32) = x"AA" or datain(39 downto 32) = x"BB" or datain(39 downto 32) = x"CC" then
+ dataout_i <= datain(31 downto 0);
+ dataout_valid_i <= '1';
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ dataout <= dataout_i;
+ dataout_valid <= dataout_valid_i;
+ counterA <= counterA_i;
+ counterB <= counterB_i;
+ counterC <= counterC_i;
+ counterD <= counterD_i;
+
+end architecture;
fifo_full_o : out std_logic);
end component FiFoDataMux;
- component FIFO_40_512 is
- port (
- Data : in std_logic_vector(39 downto 0);
- Clock : in std_logic;
- WrEn : in std_logic;
- RdEn : in std_logic;
- Reset : in std_logic;
- Q : out std_logic_vector(39 downto 0);
- WCNT : out std_logic_vector(9 downto 0);
- Empty : out std_logic;
- Full : out std_logic);
- end component FIFO_40_512;
-
- component DataWidthConversion is
- generic (
- g_datawidthfifo : integer := 40;
- g_datawidthtrb : integer := 32);
- port (
- clk : in std_logic;
- reset : in std_logic;
- fifo_empty : in std_logic;
- fifo_wrcnt : in std_logic_vector(9 downto 0);
- fifo_datain : in std_logic_vector(g_datawidthfifo - 1 downto 0);
- fifo_rden : out std_logic;
- buff_wren : out std_logic;
- dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0));
- end component DataWidthConversion;
+ component MupixDataFilter
+ port(
+ clk : in std_logic;
+ reset : in std_logic;
+ datain : in std_logic_vector(39 downto 0);
+ datain_valid : in std_logic;
+ dataout : out std_logic_vector(31 downto 0);
+ dataout_valid : out std_logic;
+ counterA : out std_logic_vector(31 downto 0);
+ counterB : out std_logic_vector(31 downto 0);
+ counterC : out std_logic_vector(31 downto 0);
+ counterD : out std_logic_vector(31 downto 0));
+end component MupixDataFilter;
component ReadoutController
generic(
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_datawidthtrb - 1 downto 0);
-
- signal fifo_data_width_empty_i : std_logic;
- signal fifo_data_width_dataout_i : std_logic_vector(g_datawidthfifo - 1 downto 0);
- signal fifo_data_width_datain_i : std_logic_vector(g_datawidthfifo - 1 downto 0);
- signal fifo_data_width_rd_i, fifo_data_width_wr_i : std_logic;
- signal fifo_data_width_cnt_i : std_logic_vector(9 downto 0);
+ signal mupix_filter_datain_i : std_logic_vector(g_datawidthfifo - 1 downto 0);
+ signal mupix_filter_datain_valid_i : std_logic;
+ signal mupix_filter_dataout_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal mupix_filter_dataout_valid_i : std_logic;
+ signal mupix_filter_counterA_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal mupix_filter_counterB_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal mupix_filter_counterC_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal mupix_filter_counterD_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
signal start_readout_slow_to_buffer : std_logic := '0';
signal start_readout : std_logic := '0';
fifo_datain => fifo_datain,
fifo_mask => multiplexer_mask,
fifo_rden => fifo_rden,
- buff_wren => fifo_data_width_wr_i,
- dataout => fifo_data_width_datain_i,
+ buff_wren => mupix_filter_datain_valid_i,
+ dataout => mupix_filter_datain_i,
wordin_freq => wordin_freq,
fifo_full_o => fifo_full_o);
- FIFO_40_512_1 : entity work.FIFO_40_512
- port map (
- Data => fifo_data_width_datain_i,
- Clock => clk,
- WrEn => fifo_data_width_wr_i,
- RdEn => fifo_data_width_rd_i,
- Reset => reset_reg,
- WCNT => fifo_data_width_cnt_i,
- Q => fifo_data_width_dataout_i,
- Empty => fifo_data_width_empty_i,
- Full => open);
-
- DataWidthConversion_1 : entity work.DataWidthConversion
- generic map (
- g_datawidthfifo => g_datawidthfifo,
- g_datawidthtrb => g_datawidthtrb)
- port map (
- clk => clk,
- reset => reset_reg,
- fifo_empty => fifo_data_width_empty_i,
- fifo_wrcnt => fifo_data_width_cnt_i,
- fifo_datain => fifo_data_width_dataout_i,
- fifo_rden => fifo_data_width_rd_i,
- buff_wren => fifo_mux_wren,
- dataout => fifo_mux_data_out);
+ MupixDataFilter_1 : MupixDataFilter
+ port map(
+ clk => clk,
+ reset => reset_reg,
+ datain => mupix_filter_datain_i,
+ datain_valid => mupix_filter_datain_valid_i,
+ dataout => mupix_filter_dataout_i,
+ dataout_valid => mupix_filter_dataout_valid_i,
+ counterA => mupix_filter_counterA_i,
+ counterB => mupix_filter_counterB_i,
+ counterC => mupix_filter_counterC_i,
+ counterD => mupix_filter_counterD_i);
cycl_buffer_1 : entity work.CircularMemory
generic map(
port map(
clk => clk,
rst => reset_reg,
- wr_en => fifo_mux_wren,
- data_in => fifo_mux_data_out,
+ wr_en => mupix_filter_dataout_valid_i,
+ data_in => mupix_filter_dataout_i,
rd_en => readout_controller_rd_en,
offset_en => readout_controller_offset_en,
offset => readout_words,
--0x109: circular memory input word frequency (read-only)
--0x10a: circular memory output word frequency (read-only)
--0x10b: readout controller read-enable (debug read-only)
+ --0x10c: counter link A (read-only)
+ --0x10d: counter link B (read-only)
+ --0x10e: counter link C (read-only)
+ --0x10f: counter link D (read-only)
-----------------------------------------------------------------------------------
slv_bus_handler : process(clk) is
begin
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 x"010c" =>
+ SLV_DATA_OUT <= mupix_filter_counterA_i;
+ SLV_ACK_OUT <= '1';
+ when x"010d" =>
+ SLV_DATA_OUT <= mupix_filter_counterB_i;
+ SLV_ACK_OUT <= '1';
+ when x"010e" =>
+ SLV_DATA_OUT <= mupix_filter_counterC_i;
+ SLV_ACK_OUT <= '1';
+ when x"010f" =>
+ SLV_DATA_OUT <= mupix_filter_counterD_i;
+ SLV_ACK_OUT <= '1';
when others =>
slv_unknown_addr_out <= '1';
end case;
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+entity MupixDataFilterTest is
+end entity;
+
+architecture sim of MupixDataFilterTest is
+
+ component MupixDataFilter
+ port(
+ clk : in std_logic; -- clock input
+ reset : in std_logic; -- reset input
+ datain : in std_logic_vector(39 downto 0); -- data in
+ datain_valid : in std_logic; -- data in valid signal
+ dataout : out std_logic_vector(31 downto 0); -- data out
+ dataout_valid : out std_logic; -- data out valid signal
+ counterA : out std_logic_vector(31 downto 0); -- last counter value link A
+ counterB : out std_logic_vector(31 downto 0); -- last counter value link B
+ counterC : out std_logic_vector(31 downto 0); -- last counter value link C
+ counterD : out std_logic_vector(31 downto 0) -- last counter value link D
+ );
+end component MupixDataFilter;
+
+constant clk_period : time := 10 ns;
+
+signal clk : std_logic;
+signal reset : std_logic := '0';
+signal datain : std_logic_vector(39 downto 0) := (others => '0');
+signal datain_valid : std_logic := '0';
+signal dataout : std_logic_vector(31 downto 0);
+signal dataout_valid : std_logic;
+signal counterA : std_logic_vector(31 downto 0);
+signal counterB : std_logic_vector(31 downto 0);
+signal counterC : std_logic_vector(31 downto 0);
+signal counterD : std_logic_vector(31 downto 0);
+
+begin
+
+ dut : MupixDataFilter
+ port map(
+ clk => clk,
+ reset => reset,
+ datain => datain,
+ datain_valid => datain_valid,
+ dataout => dataout,
+ dataout_valid => dataout_valid,
+ counterA => counterA,
+ counterB => counterB,
+ counterC => counterC,
+ counterD => counterD);
+
+ clk_gen : process
+ begin
+ clk <= '1';
+ wait for clk_period/2;
+ clk <= '0';
+ wait for clk_period/2;
+ end process;
+
+ stimulus : process
+ begin
+ wait for 100 ns;
+ -- writing hit data
+ datain_valid <= '1';
+ datain <= x"AAC0FEBABE";
+ wait for clk_period;
+ datain <= x"BBFABEABBA";
+ wait for clk_period;
+ datain <= x"CCBEEFBEEF";
+ wait for clk_period;
+ datain <= x"DDBABEC0FE";
+ wait for clk_period;
+ datain_valid <= '0';
+ wait for 50 ns;
+ -- writing counter data
+ datain_valid <= '1';
+ datain <= x"3AC0FEBABE";
+ wait for clk_period;
+ datain <= x"3BFABEABBA";
+ wait for clk_period;
+ datain <= x"3CBEEFBEEF";
+ wait for clk_period;
+ datain <= x"3DBABEC0FE";
+ wait for clk_period;
+ datain_valid <= '0';
+
+ end process;
+
+end architecture;