From 8c86d1bc34e57bc6dfd4af598575f8507a8c8d54 Mon Sep 17 00:00:00 2001 From: Tobias Weber Date: Wed, 9 Aug 2017 17:20:44 +0200 Subject: [PATCH] Rewriting the Hitbus/Latency Histogram to use external triggers for latency measurement. --- mupix/sources/Histogram.vhd | 12 +-- mupix/sources/HitbusHistogram.vhd | 106 ++++++++++++--------- mupix/sources/MuPix3_board.vhd | 18 ++-- mupix/sources/MuPix3_boardinterface.vhd | 19 ++-- mupix/sources/TimeWalk.vhd | 1 - mupix/sources/mupix_components.vhd | 18 ++-- mupix/tb/HitbusHistogramTest.vhd | 120 ++++++++++++++++++++++++ 7 files changed, 221 insertions(+), 73 deletions(-) create mode 100644 mupix/tb/HitbusHistogramTest.vhd diff --git a/mupix/sources/Histogram.vhd b/mupix/sources/Histogram.vhd index 99337d4..34e30eb 100644 --- a/mupix/sources/Histogram.vhd +++ b/mupix/sources/Histogram.vhd @@ -21,11 +21,6 @@ library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; --- Uncomment the following library declaration if instantiating --- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; - entity Histogram is generic ( HistogramHeight : integer := 12; -- Bin Height in power of two @@ -104,11 +99,13 @@ begin elsif Reset = '1' then Histo_fsm <= Clear; Overflow <= '0'; + else + Histo_fsm <= Idle; end if; when WriteHisto => if delcounter = 1 then - MemWrAddr <= BinSelect; + MemWrAddr <= MemRdAddr; MemWrEn <= '1'; delcounter <= 0; Histo_fsm <= idle; @@ -125,7 +122,8 @@ begin end if; when WaitOnMem => - Histo_fsm <= ReadHisto; + Histo_fsm <= ReadHisto; + when ReadHisto => BinHeight <= MemDOut; DataValid <= '1'; diff --git a/mupix/sources/HitbusHistogram.vhd b/mupix/sources/HitbusHistogram.vhd index 58fdc96..a2a5135 100644 --- a/mupix/sources/HitbusHistogram.vhd +++ b/mupix/sources/HitbusHistogram.vhd @@ -9,11 +9,12 @@ use IEEE.NUMERIC_STD.all; entity HitbusHistogram is generic ( - HistogramRange : integer := 8); + HistogramRange : integer := 8; + PostOscillationWaitCycles : integer := 5); port ( clk : in std_logic; hitbus : in std_logic; - Trigger : out std_logic; --Trigger to Laser/LED + trigger : in std_logic; --Trigger from Laser or scintillator SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; SLV_DATA_OUT : out std_logic_vector(31 downto 0); @@ -43,9 +44,20 @@ architecture Behavioral of HitbusHistogram is BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0)); end component; + component SignalDelay is + generic ( + Width : integer; + Delay : integer); + port ( + clk_in : in std_logic; + write_en_in : in std_logic; + delay_in : in std_logic_vector(Delay - 1 downto 0); + sig_in : in std_logic_vector(Width - 1 downto 0); + sig_out : out std_logic_vector(Width - 1 downto 0)); + end component SignalDelay; signal hitbus_i : std_logic_vector(1 downto 0); - signal hitbus_buffer : std_logic; + signal trigger_i : std_logic_vector(1 downto 0); --ToT Histogram type hithisto_fsm_type is (idle, hitbus_high, wait_for_postOscillation); @@ -58,10 +70,8 @@ architecture Behavioral of HitbusHistogram is --Latency Histogram - type latency_fsm_type is (idle, waittime, generatetrigger, waitforhitbus); + type latency_fsm_type is (idle, waitforhitbus); signal latency_fsm : latency_fsm_type := idle; - signal trigger_counter : unsigned(2 downto 0) := (others => '0'); - signal wait_counter : unsigned(15 downto 0) := (others => '0'); signal latency_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high signal latency_HistoWrAddr : std_logic_vector(HistogramRange - 1 downto 0); signal latency_WriteBin : std_logic; @@ -76,7 +86,10 @@ architecture Behavioral of HitbusHistogram is signal ReadHisto : std_logic := '0'; signal reading_histo_mem : std_logic := '0'; --read in progress signal readcounter : unsigned(HistogramRange - 1 downto 0) := (others => '0'); + signal hitbus_wait : unsigned(HistogramRange - 1 downto 0) := (others => '0'); + signal hitbus_delayed : std_logic; + begin @@ -109,13 +122,24 @@ begin BinSelect => latency_HistoWrAddr, DataValid => open, BinHeight => latency_BinValue); + + SignalDelay_1: entity work.SignalDelay + generic map ( + Width => 1, + Delay => 5) + port map ( + clk_in => clk, + write_en_in => '1', + delay_in => std_logic_vector(to_unsigned(5, 5)), + sig_in(0) => hitbus, + sig_out(0) => hitbus_delayed); - -- purpose: hitbus synchronize and edge detect + -- purpose: hitbus and trigger edge detect hitbus_edge_proc: process (clk) is begin -- process hitbus_edge_proc if rising_edge(clk) then - hitbus_buffer <= hitbus; - hitbus_i <= hitbus_i(0) & hitbus_buffer; + hitbus_i <= hitbus_i(0) & hitbus_delayed; + trigger_i <= trigger_i(0) & trigger; end if; end process hitbus_edge_proc; @@ -127,27 +151,31 @@ begin if rising_edge(clk) then hitbus_WriteBin <= '0'; postOscillationCounter <= (others => '0'); + hitbus_HistoWrAddr <= (others => '0'); case hithisto_fsm is when idle => hitbus_counter <= (others => '0'); - if hitbus_i = "01" then --rising edge + hithisto_fsm <= idle; + if hitbus_i = "01" then --rising edge on hitbus hithisto_fsm <= hitbus_high; end if; when hitbus_high => hitbus_counter <= hitbus_counter + 1; + hithisto_fsm <= hitbus_high; if hitbus_i = "10" then --falling edge hithisto_fsm <= wait_for_postOscillation; end if; when wait_for_postOscillation => postOscillationCounter <= postOscillationCounter + 1; - if(to_integer(postOscillationCounter) = 5) then --wait 5 clock cycles + if(to_integer(postOscillationCounter) = PostOscillationWaitCycles) then --wait 5 clock cycles hitbus_WriteBin <= '1'; hitbus_HistoWrAddr <= std_logic_vector(hitbus_counter); hithisto_fsm <= idle; - end if; - if(hitbus_i = "01") then --new rising edge cut belong to the same event + elsif(hitbus_i = "01") then --new rising edge, belongs to the same event hitbus_counter <= hitbus_counter + postOscillationCounter + 1; hithisto_fsm <= hitbus_high; + else + hithisto_fsm <= wait_for_postOscillation; end if; end case; end if; @@ -156,47 +184,31 @@ begin ----------------------------------------------------------------------------- --Latency Histogram ----------------------------------------------------------------------------- - LatencyHisto : process(clk) begin -- process LatencyHisto - if rising_edge(clk) then + if rising_edge(clk) then + latency_histoWraddr <= (others => '0'); + latency_WriteBin <= '0'; case latency_fsm is when idle => - trigger_counter <= (others => '0'); - --latency_histoaddr <= (others => '0'); - latency_counter <= (others => '0'); - latency_WriteBin <= '0'; - if histo_ctrl(3) = '1' then - latency_fsm <= waittime; - wait_counter <= wait_counter + 1; - end if; - - when waittime => - wait_counter <= wait_counter + 1; - if std_logic_vector(wait_counter) = histo_ctrl(31 downto 16) then - trigger <= '1'; - latency_fsm <= generatetrigger; - end if; - when generatetrigger => --necessary width of triggersignal in - --function generator? - trigger_counter <= trigger_counter + 1; - if trigger_counter = "111" then - latency_fsm <= waitforhitbus; + if trigger_i = "01" then + latency_fsm <= waitforhitbus; + latency_counter <= latency_counter + 1; else - latency_fsm <= generatetrigger; + latency_fsm <= idle; + latency_counter <= (others => '0'); end if; - latency_counter <= latency_counter + 1; - wait_counter <= (others => '0'); - + when waitforhitbus => - trigger <= '0'; latency_counter <= latency_counter + 1; if hitbus_i = "01" then latency_writebin <= '1'; latency_histoWraddr <= std_logic_vector(latency_counter); latency_fsm <= idle; - elsif latency_counter = x"FFFF" then - latency_fsm <= idle; + elsif latency_counter = hitbus_wait then + latency_fsm <= idle; + else + latency_fsm <= waitforhitbus; end if; end case; end if; @@ -210,6 +222,7 @@ begin --0x0803: Read Histograms --0x0804: ReadCounter --0x0805: snapshot of hitbus + --0x0806: max wait time for hitbus event after latency trigger has been seen ----------------------------------------------------------------------------- SLV_BUS_HANDLER : process(clk) begin -- process SLV_BUS_HANDLER @@ -219,6 +232,7 @@ begin SLV_UNKNOWN_ADDR_OUT <= '0'; SLV_NO_MORE_DATA_OUT <= '0'; histvalue <= latency_BinValue & hitbus_BinValue; + if reading_histo_mem = '1' then ReadHisto <= '0'; if histvalue_valid = '1' then @@ -253,6 +267,9 @@ begin when x"0805" => SLV_DATA_OUT(0) <= hitbus; SLV_ACK_OUT <= '1'; + when x"0806" => + SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(hitbus_wait); + SLV_ACK_OUT <= '1'; when others => SLV_UNKNOWN_ADDR_OUT <= '1'; end case; @@ -265,10 +282,13 @@ begin when x"0804" => readcounter <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0)); SLV_ACK_OUT <= '1'; + when x"0806" => + hitbus_wait <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0)); + SLV_ACK_OUT <= '1'; when others => SLV_UNKNOWN_ADDR_OUT <= '1'; end case; - + end if; end if; diff --git a/mupix/sources/MuPix3_board.vhd b/mupix/sources/MuPix3_board.vhd index f1c73a2..e49a93d 100644 --- a/mupix/sources/MuPix3_board.vhd +++ b/mupix/sources/MuPix3_board.vhd @@ -121,8 +121,10 @@ architecture Behavioral of MuPix3_Board is signal sout_c_from_mupix_sync : std_logic; signal sout_d_from_mupix_sync : std_logic; signal hbus_from_mupix_sync : std_logic; - signal fpga_aux_from_board_sync : std_logic_vector(5 downto 0); + signal hbus_from_mupix_fast_sync : std_logic; + signal fpga_aux_from_board_sync : std_logic_vector(4 downto 0); signal szintilator_sync : std_logic; + signal szintilator_fast_sync : std_logic; signal mupix_ctrl_i : MupixSlowControl; @@ -212,8 +214,10 @@ begin -- Behavioral sout_c_from_mupix_sync => sout_c_from_mupix_sync, sout_d_from_mupix_sync => sout_d_from_mupix_sync, hbus_from_mupix_sync => hbus_from_mupix_sync, + hbus_from_mupix_fast_sync => hbus_from_mupix_fast_sync, fpga_aux_from_board_sync => fpga_aux_from_board_sync, szintilator_sync => szintilator_sync, + szintilator_fast_sync => szintilator_fast_sync, SLV_READ_IN => slv_read(7), SLV_WRITE_IN => slv_write(7), @@ -308,10 +312,10 @@ begin -- Behavioral HitbusHistogram_1 : HitbusHistogram generic map ( - HistogramRange => 10) + HistogramRange => 9) port map ( clk => clk, - trigger => fpga_aux_to_board(0), + trigger => szintilator_sync, hitbus => hbus_from_mupix_sync, SLV_READ_IN => slv_read(4), SLV_WRITE_IN => slv_write(4), @@ -388,8 +392,8 @@ begin -- Behavioral trb_slv_clock => clk, fast_clk => fast_clk, reset => reset, - hitbus => hbus_from_mupix_sync, - szintillator_trigger => szintilator_sync, + hitbus => hbus_from_mupix_fast_sync, + szintillator_trigger => szintilator_fast_sync, SLV_READ_IN => slv_read(8), SLV_WRITE_IN => slv_write(8), SLV_DATA_OUT => slv_data_rd(8*32+31 downto 8*32), @@ -400,7 +404,7 @@ begin -- Behavioral SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(8)); --set unused signals to board 0 - fpga_led_to_board <= (others => '0'); - fpga_aux_to_board(3 downto 1) <= (others => '0'); + fpga_led_to_board <= (others => '0'); + fpga_aux_to_board(3 downto 0) <= (others => '0'); end Behavioral; diff --git a/mupix/sources/MuPix3_boardinterface.vhd b/mupix/sources/MuPix3_boardinterface.vhd index 22175f7..af0a213 100644 --- a/mupix/sources/MuPix3_boardinterface.vhd +++ b/mupix/sources/MuPix3_boardinterface.vhd @@ -27,8 +27,10 @@ entity board_interface is sout_c_from_mupix_sync : out std_logic; sout_d_from_mupix_sync : out std_logic; hbus_from_mupix_sync : out std_logic; - fpga_aux_from_board_sync : out std_logic_vector(5 downto 0); - szintilator_sync : out std_logic; + hbus_from_mupix_fast_sync : out std_logic; + fpga_aux_from_board_sync : out std_logic_vector(4 downto 0); + szintilator_sync : out std_logic; + szintilator_fast_sync : out std_logic; --Trb Slv-Bus SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; @@ -55,12 +57,12 @@ begin begin -- process fast_sync if rising_edge(fast_clk_in) then hitbus_buf <= hbus_from_mupix; - szintilator_sync_buf <= fpga_aux_from_board(0); - szintilator_sync <= szintilator_sync_buf; + szintilator_sync_buf <= fpga_aux_from_board(0); + szintilator_fast_sync <= szintilator_sync_buf; if invert_signals_int = '1' then - hbus_from_mupix_sync <= hitbus_buf; + hbus_from_mupix_fast_sync <= hitbus_buf; else - hbus_from_mupix_sync <= not hitbus_buf; + hbus_from_mupix_fast_sync <= not hitbus_buf; end if; end if; end process fast_sync; @@ -69,7 +71,8 @@ begin process begin wait until rising_edge(clk_in); - fpga_aux_from_board_sync <= fpga_aux_from_board; + fpga_aux_from_board_sync <= fpga_aux_from_board(5 downto 1); + szintilator_sync <= fpga_aux_from_board(0); if invert_signals_int = '1' then mupixreadout_sync.hit_time <= not mupixreadout.hit_time; mupixreadout_sync.hit_row <= not mupixreadout.hit_row; @@ -77,6 +80,7 @@ begin mupixreadout_sync.priout <= mupixreadout.priout; --is inverted on the chip sout_c_from_mupix_sync <= not sout_c_from_mupix; sout_d_from_mupix_sync <= not sout_d_from_mupix; + hbus_from_mupix_sync <= hbus_from_mupix; else mupixreadout_sync.hit_time <= mupixreadout.hit_time; mupixreadout_sync.hit_row <= mupixreadout.hit_row; @@ -84,6 +88,7 @@ begin mupixreadout_sync.priout <= not mupixreadout.priout; --is inverted on the chip sout_c_from_mupix_sync <= sout_c_from_mupix; sout_d_from_mupix_sync <= sout_d_from_mupix; + hbus_from_mupix_sync <= not hbus_from_mupix; end if; end process; diff --git a/mupix/sources/TimeWalk.vhd b/mupix/sources/TimeWalk.vhd index 23736ee..8877d5e 100644 --- a/mupix/sources/TimeWalk.vhd +++ b/mupix/sources/TimeWalk.vhd @@ -99,7 +99,6 @@ begin -- architecture TimeWalk_Arch measurementData <= std_logic_vector(latencycounter & hitbuscounter); measurementFinished <= '1'; end if; - when others => null; end case; end if; end process TimeWalk_Measurement; diff --git a/mupix/sources/mupix_components.vhd b/mupix/sources/mupix_components.vhd index b1ea9fa..7624e7f 100644 --- a/mupix/sources/mupix_components.vhd +++ b/mupix/sources/mupix_components.vhd @@ -133,7 +133,7 @@ package mupix_components is port ( clk : in std_logic; hitbus : in std_logic; - Trigger : out std_logic; + Trigger : in std_logic; SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; SLV_DATA_OUT : out std_logic_vector(31 downto 0); @@ -255,16 +255,18 @@ package mupix_components is clk_in : in std_logic; fast_clk_in : in std_logic; mupixreadout : in MupixReadoutData; - sout_c_from_mupix : in std_logic; - sout_d_from_mupix : in std_logic; - hbus_from_mupix : in std_logic; - fpga_aux_from_board : in std_logic_vector(5 downto 0); + sout_c_from_mupix : in std_logic; + sout_d_from_mupix : in std_logic; + hbus_from_mupix : in std_logic; + fpga_aux_from_board : in std_logic_vector(5 downto 0); mupixreadout_sync : out MupixReadoutData; sout_c_from_mupix_sync : out std_logic; sout_d_from_mupix_sync : out std_logic; - hbus_form_mupix_sync : out std_logic; - fpga_aux_from_board_sync : out std_logic_vector(5 downto 0); + hbus_from_mupix_sync : out std_logic; + hbus_from_mupix_fast_sync : out std_logic; + fpga_aux_from_board_sync : out std_logic_vector(4 downto 0); szintilator_sync : out std_logic; + szintilator_fast_sync : 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); @@ -272,7 +274,7 @@ package mupix_components is 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_UNKNOWN_ADDR_OUT : out std_logic); end component board_interface; component resethandler is diff --git a/mupix/tb/HitbusHistogramTest.vhd b/mupix/tb/HitbusHistogramTest.vhd new file mode 100644 index 0000000..b788f08 --- /dev/null +++ b/mupix/tb/HitbusHistogramTest.vhd @@ -0,0 +1,120 @@ +------------------------------------------------------------ +--! @file +--! @brief Testbench for readout of Mupix 3-6 +--! @author Tobias Weber +--! @date August 2017 +------------------------------------------------------------ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.TRBSimulationPkg.all; + +entity HitbusHistogramTest is +end entity HitbusHistogramTest; + +architecture simulation of HitbusHistogramTest is + + component HitbusHistogram + generic( + HistogramRange : integer := 6; + PostOscillationWaitCycles : integer := 5 + ); + port( + clk : in std_logic; + hitbus : in std_logic; + trigger : in 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 HitbusHistogram; + + constant HistogramRange : integer := 6; + constant PostOscillationWaitCycles : integer := 5; + constant clk_period : time := 10 ns; + + signal clk : std_logic := '0'; + signal hitbus : std_logic := '0'; + signal trigger : std_logic := '0'; + signal SLV_READ_IN : std_logic := '0'; + signal SLV_WRITE_IN : std_logic := '0'; + signal SLV_DATA_IN : std_logic_vector(31 downto 0) := (others => '0'); + signal SLV_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0'); + + + signal SLV_DATA_OUT : std_logic_vector(31 downto 0); + signal SLV_ACK_OUT : std_logic; + signal SLV_NO_MORE_DATA_OUT : std_logic; + signal SLV_UNKNOWN_ADDR_OUT : std_logic; + + procedure HitbusEvent(signal hitbus, trigger : out std_logic; + constant latency, tot1 : time; + constant postoscillation, tot2 : time := 0 ns) is + begin + trigger <= '1'; + wait for latency; + trigger <= '0'; + hitbus <= '1'; + wait for tot1; + hitbus <= '0'; + if postoscillation > 0 ns then + wait for postoscillation; + hitbus <= '1'; + wait for tot2; + hitbus <= '0'; + end if; + wait for 200 ns; + end procedure HitbusEvent; + + +begin + + HitbusHistogram_1 : entity work.HitbusHistogram + generic map( + HistogramRange => HistogramRange, + PostOscillationWaitCycles => PostOscillationWaitCycles + ) + port map( + clk => clk, + hitbus => hitbus, + trigger => trigger, + SLV_READ_IN => SLV_READ_IN, + SLV_WRITE_IN => SLV_WRITE_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 + ); + + clk_gen : process is + begin + clk <= '1'; + wait for clk_period/2; + clk <= '0'; + wait for clk_period/2; + end process clk_gen; + + stimulus : process is + begin + wait for 100 ns; + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"000000FF", x"0806"); + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(2, 32)), x"0800"); + for i in 0 to 5 loop + HitbusEvent(hitbus, trigger, 50 ns, 100 ns); + end loop; + for i in 0 to 8 loop + HitbusEvent(hitbus, trigger, 50 ns, 120 ns); + end loop; + HitbusEvent(hitbus, trigger, 50 ns, 100 ns, 20 ns, 30 ns);--test post-oscillation + wait; + end process stimulus; + + +end architecture simulation; -- 2.43.0