--- /dev/null
+----------------------------------------------------------------------------------
+-- MuPix8 Column and Row Address Decoder
+-- and ToT and Timestamp Gray Decoder
+-- René Hagdorn
+-- Ruhr-University Bochum
+----------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+entity DataDecoder is
+ generic (
+ D_W : integer := 32; -- width of full data word
+ Pix_W : integer := 8; -- col/row address width
+ ToT_W : integer := 6; -- time over threshold width
+ TS_W : integer := 10; -- timestamp width
+ LINKS : integer := 4 -- number of links (data + counters)
+ );
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ bypass : in std_logic;
+ datain : in std_logic_vector(D_W - 1 downto 0); -- incoming data word
+ datain_valid : in std_logic; -- valid signal for input data
+ counterA_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link A
+ counterB_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+ counterC_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+
+ dataout : out std_logic_vector(D_W - 1 downto 0); -- decoded data word
+ dataout_valid : out std_logic; -- valid output data
+ counterA_out : out std_logic_vector(D_W - 1 downto 0); -- last counter value link A
+ counterB_out : out std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+ counterC_out : out std_logic_vector(D_W - 1 downto 0) -- last counter value link B
+ );
+end DataDecoder;
+
+architecture RTL of DataDecoder is
+
+component PixelAddressDecode is
+ generic (
+ column_width : integer := 8; -- column bits
+ row_width : integer := 8); -- row bits
+ port (
+ clk : in std_logic; -- clock in
+ reset : in std_logic; -- reset in
+ bypass : in std_logic; -- bypass logic
+ ena : in std_logic; -- enable in
+ col_in : in std_logic_vector(column_width - 1 downto 0); -- mupix col addr.
+ row_in : in std_logic_vector(row_width - 1 downto 0); -- mupix row addr.
+ valid_o : out std_logic; -- valid output
+ col_out : out std_logic_vector(column_width - 1 downto 0); -- phys. col addr.
+ row_out : out std_logic_vector(row_width - 1 downto 0)); -- phys row addr.
+end component;
+
+component gray_to_binary is
+ generic(NBITS : integer := 10);
+ port (
+ clk : in std_logic; -- clk input
+ reset : in std_logic; -- reset input
+ bypass : in std_logic; -- bypass logic
+ gray_in : in std_logic_vector (NBITS - 1 downto 0); -- gray counter input
+ bin_out : out std_logic_vector (NBITS - 1 downto 0) -- binary counter output
+ );
+end component;
+
+signal datain_i : std_logic_vector(LINKS*D_W - 1 downto 0); -- data channel and counters
+signal dataout_i : std_logic_vector(LINKS*D_W - 1 downto 0); -- data channel and counters
+signal validin_i : std_logic_vector(LINKS - 1 downto 0);
+signal validout_i : std_logic_vector(LINKS - 1 downto 0); -- valid signals
+
+begin
+
+ -- combine datain and counters to single stream for easier decoder generation
+ datain_i <= datain & counterA_in & counterB_in & counterC_in;
+ validin_i <= datain_valid & b"111";
+
+ Decode_J : for J in 1 to LINKS generate
+ address_decoder : PixelAddressDecode
+ generic map (
+ column_width => Pix_W,
+ row_width => Pix_W
+ )
+ port map (
+ clk => clk,
+ reset => reset,
+ bypass => bypass,
+ ena => validin_i(J - 1),
+ col_in => datain_i(J*D_W - Pix_W - 1 downto J*D_W - 2*Pix_W),
+ row_in => datain_i(J*D_W - 1 downto J*D_W - Pix_W),
+ valid_o => validout_i(J - 1),
+ col_out => dataout_i(J*D_W - Pix_W - 1 downto J*D_W - 2*Pix_W),
+ row_out => dataout_i(J*D_W - 1 downto J*D_W - Pix_W)
+ );
+
+ ToT_decoder : gray_to_binary
+ generic map (
+ NBITS => ToT_W
+ )
+ port map (
+ clk => clk,
+ reset => reset,
+ bypass => bypass,
+ gray_in => datain_i(J*D_W - 2*Pix_W - 1 downto (J-1)*D_W + TS_W),
+ bin_out => dataout_i(J*D_W - 2*Pix_W - 1 downto (J-1)*D_W + TS_W)
+ );
+
+ Timestamp_decoder : gray_to_binary
+ generic map (
+ NBITS => TS_W
+ )
+ port map (
+ clk => clk,
+ reset => reset,
+ bypass => bypass,
+ gray_in => datain_i((J-1)*D_W + TS_W - 1 downto (J-1)*D_W),
+ bin_out => dataout_i((J-1)*D_W + TS_W - 1 downto (J-1)*D_W)
+ );
+ end generate Decode_J;
+
+ -- split datastream back up to individual outputs
+ dataout_valid <= validout_i(LINKS - 1);
+ dataout <= dataout_i(LINKS*D_W - 1 downto (LINKS - 1)*D_W);
+ counterA_out <= dataout_i((LINKS - 1)*D_W - 1 downto (LINKS - 2)*D_W);
+ counterB_out <= dataout_i((LINKS - 2)*D_W - 1 downto (LINKS - 3)*D_W);
+ counterC_out <= dataout_i((LINKS - 3)*D_W - 1 downto (LINKS - 4)*D_W);
+
+end RTL;
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));
-end component MupixDataFilter;
+ 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));
+ end component MupixDataFilter;
+
+ component DataDecoder
+ generic (
+ D_W : integer := 32; -- width of full data word
+ Pix_W : integer := 8; -- col/row address width
+ ToT_W : integer := 6; -- time over threshold width
+ TS_W : integer := 10; -- timestamp width
+ LINKS : integer := 4 -- number of links (data + counters)
+ );
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ bypass : in std_logic;
+ datain : in std_logic_vector(D_W - 1 downto 0); -- incoming data word
+ datain_valid : in std_logic; -- valid signal for input data
+ counterA_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link A
+ counterB_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+ counterC_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link C
+
+ dataout : out std_logic_vector(D_W - 1 downto 0); -- decoded data word
+ dataout_valid : out std_logic; -- valid output data
+ counterA_out : out std_logic_vector(D_W - 1 downto 0); -- last counter value link A
+ counterB_out : out std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+ counterC_out : out std_logic_vector(D_W - 1 downto 0) -- last counter value link C
+ );
+ end component DataDecoder
component ReadoutController
generic(
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 decoder_bypass_i : std_logic := '0';
+ signal decoder_dataout_valid_i : std_logic;
+ signal decoder_dataout_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal decoder_counterA_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal decoder_counterB_i : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal decoder_counterC_i : std_logic_vector(g_datawidthtrb - 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_datawidthtrb - 1 downto 0);
counterB => mupix_filter_counterB_i,
counterC => mupix_filter_counterC_i);
+ DataDecoder_1 : DataDecoder
+ generic map (
+ D_W => g_datawidthtrb,
+ Pix_W => 8,
+ ToT_W => 6,
+ TS_W => 10,
+ LINKS => g_mupix_links
+ )
+ port map (
+ clk => clk
+ reset => reset_reg,
+ bypass => converter_bypass_i,
+ datain => mupix_filter_dataout_i,
+ datain_valid => mupix_filter_dataout_valid_i,
+ counterA_in => mupix_filter_counterA_i,
+ counterB_in => mupix_filter_counterB_i,
+ counterC_in => mupix_filter_counterC_i,
+
+ dataout => decoder_dataout_i,
+ dataout_valid => decoder_dataout_valid_i,
+ counterA_out => decoder_counterA_i,
+ counterB_out => decoder_counterB_i,
+ counterC_out => decoder_counterC_i,
+ );
+
cycl_buffer_1 : entity work.CircularMemory
generic map(
g_datawidth => g_datawidthtrb,
port map(
clk => clk,
rst => reset_reg,
- wr_en => mupix_filter_dataout_valid_i,
- data_in => mupix_filter_dataout_i,
+ wr_en => decoder_dataout_valid_i,
+ data_in => decoder_dataout_i,
rd_en => readout_controller_rd_en,
offset_en => readout_controller_offset_en,
offset => readout_words,
--0x10c: counter link A (read-only)
--0x10d: counter link B (read-only)
--0x10e: counter link C (read-only)
+ --0x10f: address/gray decoder bypass
-----------------------------------------------------------------------------------
slv_bus_handler : process(clk) is
begin
when x"0106" =>
multiplexer_channel_sel <= to_integer(unsigned(SLV_DATA_IN_i));
SLV_ACK_OUT <= '1';
+ when x"010f" =>
+ decoder_bypass_i <= SLV_DATA_IN_i(0);
+ SLV_ACK_OUT <= '1';
when others =>
slv_unknown_addr_out <= '1';
end case;
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_DATA_OUT <= decoder_counterA_i;
SLV_ACK_OUT <= '1';
when x"010d" =>
- SLV_DATA_OUT <= mupix_filter_counterB_i;
+ SLV_DATA_OUT <= decoder_counterB_i;
SLV_ACK_OUT <= '1';
when x"010e" =>
- SLV_DATA_OUT <= mupix_filter_counterC_i;
+ SLV_DATA_OUT <= decoder_counterC_i;
SLV_ACK_OUT <= '1';
+ when x"010f" =>
+ SLV_DATA_OUT(0) <= decoder_bypass_i;
+ SLV_ACK_OUT <= '1';
when others =>
slv_unknown_addr_out <= '1';
end case;
-------------------------------------------------------------
+-----------------------------------------------------------
-- Decoding of pixel address of Mupix 8 to physical address
-- T.Weber
-- Ruhr University Bochum
--- /dev/null
+----------------------------------------------------------------------------------
+-- DataConverter & DataFilter Testbench
+-- René Hagdorn
+-- Ruhr-University Bochum
+----------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+entity DataDecoder_TB is
+ generic (
+ D_W : integer := 32;
+ Pix_W : integer := 8;
+ ToT_W : integer := 6;
+ TS_W : integer := 10;
+ LINKS : integer := 4;
+ clkcyc: time := 10 ns
+ );
+end DataDecoder_TB;
+
+architecture Behavioral of DataDecoder_TB is
+
+component 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
+end component;
+
+component DataDecoder is
+ generic (
+ D_W : integer := 32; -- width of full data word
+ Pix_W : integer := 8; -- col/row address width
+ ToT_W : integer := 6; -- time over threshold width
+ TS_W : integer := 10; -- timestamp width
+ LINKS : integer := 4 -- number of links (data + counters)
+ );
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ bypass : in std_logic;
+ datain : in std_logic_vector(D_W - 1 downto 0); -- incoming data word
+ datain_valid : in std_logic; -- valid signal for input data
+ counterA_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link A
+ counterB_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+ counterC_in : in std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+
+ dataout : out std_logic_vector(D_W - 1 downto 0); -- decoded data word
+ dataout_valid : out std_logic; -- valid output data
+ counterA_out : out std_logic_vector(D_W - 1 downto 0); -- last counter value link A
+ counterB_out : out std_logic_vector(D_W - 1 downto 0); -- last counter value link B
+ counterC_out : out std_logic_vector(D_W - 1 downto 0) -- last counter value link B
+ );
+end component;
+
+signal clk : std_logic := '0';
+signal reset : std_logic := '0';
+signal bypass : std_logic := '0';
+signal datain_filter : std_logic_vector(39 downto 0) := (others => '0');
+signal datain_v_filter : std_logic := '0';
+signal datain_converter : std_logic_vector(D_W - 1 downto 0) := (others => '0');
+signal enable_converter : std_logic := '0';
+signal counterA_valid_i : std_logic := '0';
+signal counterB_valid_i : std_logic := '0';
+signal counterC_valid_i : std_logic := '0';
+signal ctrAin_converter : std_logic_vector(D_W - 1 downto 0) := (others => '0');
+signal ctrBin_converter : std_logic_vector(D_W - 1 downto 0) := (others => '0');
+signal ctrCin_converter : std_logic_vector(D_W - 1 downto 0) := (others => '0');
+
+signal dataout_converter : std_logic_vector(D_W - 1 downto 0);
+signal dataout_v_converter : std_logic;
+signal ctrAout_converter : std_logic_vector(D_W - 1 downto 0);
+signal ctrBout_converter : std_logic_vector(D_W - 1 downto 0);
+signal ctrCout_converter : std_logic_vector(D_W - 1 downto 0);
+
+begin
+
+ filter : MupixDataFilter
+ port map(
+ clk => clk,
+ reset => reset,
+ datain => datain_filter,
+ datain_valid => datain_v_filter,
+ dataout => datain_converter,
+ dataout_valid => enable_converter,
+ counterA => ctrAin_converter,
+ counterB => ctrBin_converter,
+ counterC => ctrCin_converter
+ );
+
+ decoder : DataDecoder
+ generic map(
+ D_W => D_W,
+ Pix_W => Pix_W,
+ ToT_W => ToT_W,
+ TS_W => TS_W,
+ LINKS => LINKS
+ )
+ port map (
+ clk => clk,
+ reset => reset,
+ bypass => bypass,
+ datain => datain_converter,
+ datain_valid => enable_converter,
+ counterA_in => ctrAin_converter,
+ counterB_in => ctrBin_converter,
+ counterC_in => ctrCin_converter,
+ dataout => dataout_converter,
+ dataout_valid => dataout_v_converter,
+ counterA_out => ctrAout_converter,
+ counterB_out => ctrBout_converter,
+ counterC_out => ctrCout_converter
+ );
+
+ takt : process
+ begin
+ wait for clkcyc/2;
+ clk <= not clk;
+ end process takt;
+
+ stim : process
+ begin
+ wait for 100 ns;
+ -- first w/ converter
+ bypass <= '0';
+ wait for 2*clkcyc;
+ -- writing hit data
+ datain_v_filter <= '1';
+ datain_filter <= x"AAC0FEBABE";
+ wait for clkcyc;
+ datain_filter <= x"BBFABEABBA";
+ wait for clkcyc;
+ datain_filter <= x"CCBEEFBEEF";
+ wait for clkcyc;
+ datain_filter <= x"DDBABEC0FE";
+ wait for clkcyc;
+ datain_v_filter <= '0';
+ wait for 50 ns;
+ -- writing counter data
+ datain_v_filter <= '1';
+ datain_filter <= x"3AC0FEBABE";
+ wait for clkcyc;
+ datain_filter <= x"3BFABEABBA";
+ wait for clkcyc;
+ datain_filter <= x"3CBEEFBEEF";
+ wait for clkcyc;
+ datain_filter <= x"3DBABEC0FE";
+ wait for clkcyc;
+ datain_v_filter <= '0';
+ wait for 10*clkcyc;
+
+ reset <= '1', '0' after 2*clkcyc;
+ wait for 4*clkcyc;
+
+ -- now w/o converter
+ bypass <= '1';
+ wait for 2*clkcyc;
+ -- writing hit data
+ datain_v_filter <= '1';
+ datain_filter <= x"AAC0FEBABE";
+ wait for clkcyc;
+ datain_filter <= x"BBFABEABBA";
+ wait for clkcyc;
+ datain_filter <= x"CCBEEFBEEF";
+ wait for clkcyc;
+ datain_filter <= x"DDBABEC0FE";
+ wait for clkcyc;
+ datain_v_filter <= '0';
+ wait for 50 ns;
+ -- writing counter data
+ datain_v_filter <= '1';
+ datain_filter <= x"3AC0FEBABE";
+ wait for clkcyc;
+ datain_filter <= x"3BFABEABBA";
+ wait for clkcyc;
+ datain_filter <= x"3CBEEFBEEF";
+ wait for clkcyc;
+ datain_filter <= x"3DBABEC0FE";
+ wait for clkcyc;
+ datain_v_filter <= '0';
+ end process stim;
+
+end Behavioral;
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
+ 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;
dataout_valid => dataout_valid,
counterA => counterA,
counterB => counterB,
- counterC => counterC,
- counterD => counterD);
+ counterC => counterC);
+-- counterD => counterD);
clk_gen : process
begin
--- /dev/null
+----------------------------------------------------------------------------------
+-- Testbench for Gray Decoder by Tobias Weber
+-- René Hagdorn, Ruhr-University Bochum
+----------------------------------------------------------------------------------
+
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.NUMERIC_STD.ALL;
+
+
+entity GrayDecoder_TB is
+ generic (
+ N_BITS : integer := 10;
+ clkcnt : time := 10 ns
+ );
+end GrayDecoder_TB;
+
+architecture Behavioral of GrayDecoder_TB is
+
+component gray_to_binary is
+ generic(NBITS : integer := 10);
+ port (
+ clk : in std_logic; -- clk input
+ reset : in std_logic; -- reset input
+ bypass : in std_logic; -- bypass logic
+ gray_in : in std_logic_vector (NBITS - 1 downto 0); -- gray counter input
+ bin_out : out std_logic_vector (NBITS - 1 downto 0) -- binary counter output
+ );
+end component;
+
+signal CLK1 : std_logic := '0';
+signal RST1 : std_logic := '0';
+signal BPS1 : std_logic := '0';
+signal GRY1 : std_logic_vector(N_BITS - 1 downto 0);
+signal BIN1 : std_logic_vector(N_BITS - 1 downto 0);
+signal GRYCNT : unsigned(N_BITS - 1 downto 0) := (others => '0');
+
+begin
+
+ GRAY_DECODER: gray_to_binary
+ generic map(
+ NBITS => N_BITS
+ )
+ port map(
+ clk => CLK1,
+ reset => RST1,
+ bypass => BPS1,
+ gray_in => GRY1,
+ bin_out => BIN1
+ );
+
+ TAKT: process
+ begin
+ wait for clkcnt/2;
+ CLK1 <= not CLK1;
+ end process TAKT;
+
+ COUNTER: process(CLK1)
+ begin
+ if rising_edge(CLK1) then
+ GRYCNT <= GRYCNT + 1;
+ end if;
+ end process COUNTER;
+
+ GRY1 <= std_logic_vector(GRYCNT);
+
+ STIM: process
+ begin
+ RST1 <= '1' after 10*clkcnt, '0' after 15*clkcnt;
+ BPS1 <= '1' after 25*clkcnt, '0' after 40*clkcnt;
+ wait;
+ end process STIM;
+
+end Behavioral;
begin
- dut : entity work.MupixTRBReadout
+ dut : MupixTRBReadout
generic map(
g_mupix_links => c_mupix_links,
g_cyc_mem_address_width => c_cyc_mem_address_width,
);
gen_input_fifo : for i in 0 to 3 generate
- serdes_fifo : entity work.serdes_fifo
+ serdes_fifo_1 : serdes_fifo
port map (
Data => fifo_datain((i + 1)*c_datawidthfifo - 1 downto i*c_datawidthfifo),
WrClock => wrclk,