From be4e1b78d126eaca051be33dcfd0adc9c06310fa Mon Sep 17 00:00:00 2001 From: Tobias Weber Date: Fri, 18 Jan 2019 14:18:06 +0100 Subject: [PATCH] trying to implement a reset for the mupix timestamps. So far it is now working. --- base/trb3_periph_mupix8.lpf | 4 +- mupix/Mupix8/sources/Datapath/MupixReset.vhd | 118 ++++++++++++++++++ .../sources/Datapath/MupixTRBReadout.vhd | 10 +- .../sources/Datapath/ReadoutController.vhd | 23 +++- .../Mupix8/sources/Datapath/ResetHandler.vhd | 13 +- mupix/Mupix8/sources/MupixBoard.vhd | 24 ++++ mupix/Mupix8/trb3_periph.prj | 2 + mupix/Mupix8/trb3_periph.vhd | 2 + 8 files changed, 183 insertions(+), 13 deletions(-) create mode 100644 mupix/Mupix8/sources/Datapath/MupixReset.vhd diff --git a/base/trb3_periph_mupix8.lpf b/base/trb3_periph_mupix8.lpf index adfacbf..f9a18e2 100644 --- a/base/trb3_periph_mupix8.lpf +++ b/base/trb3_periph_mupix8.lpf @@ -23,7 +23,7 @@ IOBUF GROUP "CLK_group" IO_TYPE=LVDS25; #Trigger from fan-out LOCATE COMP "TRIGGER_LEFT" SITE "V3"; #LOCATE COMP "TRIGGER_RIGHT" SITE "N24"; -#IOBUF PORT "TRIGGER_RIGHT" IO_TYPE=LVDS25 ; +#IOBUF PORT "TRIGGER_RIGHT" IO_TYPE=LVDS25 ; IOBUF PORT "TRIGGER_LEFT" IO_TYPE=LVDS25 ; @@ -180,3 +180,5 @@ IOBUF PORT "simclk" IO_TYPE=LVDS25; ########################################################### MULTICYCLE FROM CELL "THE_RESET_HANDLER/final_reset*" 50 ns; MULTICYCLE FROM CELL "THE_RESET_HANDLER/reset" TO CELL "THE_RESET_HANDLER/final_reset[0]" 10 ns; +MULTICYCLE FROM CELL "MupixBoard8_0/mupix_reset/stretcher/stretched" 25 ns; +MULTICYCLE FROM CELL "MupixBoard8_0/mupix_reset/tsreset_reg" 25 ns; diff --git a/mupix/Mupix8/sources/Datapath/MupixReset.vhd b/mupix/Mupix8/sources/Datapath/MupixReset.vhd new file mode 100644 index 0000000..872a5b4 --- /dev/null +++ b/mupix/Mupix8/sources/Datapath/MupixReset.vhd @@ -0,0 +1,118 @@ +-------------------------------------------------------- +-- handle the reset signal to the mupix timestamps +-- Tobias Weber +-- Ruhr University Bochum +------------------------------------------------------- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity MupixReset is + port( + mupixclk : in std_logic; -- mupix clock (40-125 MHz) + trbclk : in std_logic; -- trbnet clock (100 MHz) + trbreset : in std_logic; -- trb reset + timestamp_rst : in std_logic; -- reset timestamps signal + syncres : out std_logic -- sync signal to mupix timestamp generator + ); +end entity MupixReset; + +architecture rtl of MupixReset is + + signal timestamp_ack : std_logic := '0'; -- timestamp reset acknowledge + signal tsreset_reg : std_logic := '0'; -- timestamp reset register + signal syncres_i : std_logic := '0'; + signal slowrest_i : std_logic := '0'; + + type reset_fsm is (idle, acknowledge); + type hold_fsm is (idle, hold); + signal reseter : reset_fsm := idle; + signal holder : hold_fsm := idle; + + component SignalStretcher is + generic ( + fast_clock_speed : integer; + slow_clock_speed : integer); + port ( + fast_clk : in std_logic; + reset : in std_logic; + pulse : in std_logic; + stretched : out std_logic); + end component SignalStretcher; + + begin + + stretcher: SignalStretcher + generic map( + fast_clock_speed => 10, + slow_clock_speed => 25 + ) + port map( + fast_clk => trbclk, + reset => trbreset, + pulse => trbreset, + stretched => slowrest_i + ); + + -- handshake mechanism as mupix clock is (at the moment) slower + -- than the TRB clock + hold_proc : process(trbclk) + begin + if rising_edge(trbclk) then + if trbreset = '1' then + holder <= idle; + tsreset_reg <= '0'; + else + case holder is + when idle => + if timestamp_rst = '1' then + tsreset_reg <= '1'; + holder <= hold; + end if; + when hold => + if timestamp_ack = '1' then + tsreset_reg <= '0'; + holder <= idle; + end if; + end case; + end if; + end if; + end process; + + reset_proc : process(mupixclk) + variable counter : integer range 0 to 3 := 0; + begin + if falling_edge(mupixclk) then + if slowrest_i = '1' then + syncres_i <= '0'; + timestamp_ack <= '0'; + reseter <= idle; + else + case reseter is + when idle => + counter := 0; + syncres_i <= '0'; + timestamp_ack <= '0'; + if tsreset_reg = '1' then + reseter <= acknowledge; + end if; + when acknowledge => + counter := counter + 1; + timestamp_ack <= '1'; + syncres_i <= '1'; + if counter = 3 then + reseter <= idle; + end if; + end case; + end if; + end if; + end process; + + pipe_proc : process(mupixclk) + begin + if falling_edge(mupixclk) then + syncres <= syncres_i; + end if; + end process; + +end architecture; diff --git a/mupix/Mupix8/sources/Datapath/MupixTRBReadout.vhd b/mupix/Mupix8/sources/Datapath/MupixTRBReadout.vhd index a92708e..117ee16 100644 --- a/mupix/Mupix8/sources/Datapath/MupixTRBReadout.vhd +++ b/mupix/Mupix8/sources/Datapath/MupixTRBReadout.vhd @@ -28,6 +28,8 @@ entity MupixTRBReadout is dataout : out std_logic_vector(g_datawidthtrb - 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 + eventcounter_reset : in std_logic; -- event counter reset from TRB broadcast + timestampreset : in std_logic; -- time stamp reset from TRB broadcast -- TRB slow Control channel SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; @@ -116,7 +118,7 @@ architecture rtl of MupixTRBReadout is counterA_in : in std_logic_vector(DWidth - 1 downto 0); -- last counter value link A counterB_in : in std_logic_vector(DWidth - 1 downto 0); -- last counter value link B counterC_in : in std_logic_vector(DWidth - 1 downto 0); -- last counter value link C - + dataout : out std_logic_vector(DWidth - 1 downto 0); -- decoded data word dataout_valid : out std_logic; -- valid output data counterA_out : out std_logic_vector(DWidth - 1 downto 0); -- last counter value link A @@ -141,6 +143,8 @@ architecture rtl of MupixTRBReadout is empty : in std_logic; almost_empty : in std_logic; sensor_id : in std_logic_vector(g_datawidth - 1 downto 0); + eventcounter_rst : in std_logic; + timestamprst : in std_logic; offset_en : out std_logic; rd_en : out std_logic; busy : out std_logic; @@ -261,7 +265,7 @@ begin 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, @@ -309,6 +313,8 @@ begin empty => cycl_empty, almost_empty => cycl_almost_empty, sensor_id => sensor_id, + eventcounter_rst => eventcounter_reset, + timestamprst => timestampreset, offset_en => readout_controller_offset_en, rd_en => readout_controller_rd_en, busy => readout_controller_busy, diff --git a/mupix/Mupix8/sources/Datapath/ReadoutController.vhd b/mupix/Mupix8/sources/Datapath/ReadoutController.vhd index 193b42a..2fe67c4 100644 --- a/mupix/Mupix8/sources/Datapath/ReadoutController.vhd +++ b/mupix/Mupix8/sources/Datapath/ReadoutController.vhd @@ -31,6 +31,8 @@ entity ReadoutController is 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); + eventcounter_rst : in std_logic; -- event counter reset from TRB broadcast + timestamprst : in std_logic; -- time stamp reset from TRB broadcast 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 @@ -51,6 +53,7 @@ architecture RTL of ReadoutController is signal wordcounter : unsigned(g_addresswidth - 1 downto 0) := (others => '0'); signal framecounter : unsigned(31 downto 0) := (others => '0'); + signal framecounter_inc : std_logic := '0'; signal headercounter : integer range 0 to 3 := 0; signal trailercounter : integer range 0 to 1 := 0; signal triggerwaitcounter : unsigned(g_addresswidth - 1 downto 0) := (others => '0'); @@ -63,7 +66,7 @@ begin timestamps : process(clk) begin if rising_edge(clk) then - if rst = '1' then + if rst = '1' or timestamprst = '1' then timestamp_cnt <= (others => '0'); else timestamp_cnt <= timestamp_cnt + 1; @@ -72,6 +75,19 @@ begin end if; end process timestamps; + framecnt_proc : process(clk) + begin + if rising_edge(clk) then + if rst = '1' or eventcounter_rst = '1' then + framecounter <= (others => '0'); + else + if framecounter_inc = '1' then + framecounter <= framecounter + 1; + end if; + end if; + end if; + end process framecnt_proc; + edge_detection : process (clk) is begin if rising_edge(clk) then @@ -93,7 +109,7 @@ begin busy <= '0'; data_valid <= '0'; data_out <= (others => '0'); - framecounter <= (others => '0'); + framecounter_inc <= '0'; headercounter <= 0; else busy <= '0'; @@ -101,6 +117,7 @@ begin data_out <= (others => '0'); rd_en <= '0'; offset_en <= '0'; + framecounter_inc <= '0'; case readout_fsm is when idle => trailercounter <= 0; @@ -143,7 +160,7 @@ begin headercounter <= 3; when 3 => data_out <= std_logic_vector(framecounter); - framecounter <= framecounter + 1; + framecounter_inc <= '1'; if mode = "01" then if empty = '0' then readout_fsm <= wait_memory; diff --git a/mupix/Mupix8/sources/Datapath/ResetHandler.vhd b/mupix/Mupix8/sources/Datapath/ResetHandler.vhd index 12e98ce..e096a8e 100644 --- a/mupix/Mupix8/sources/Datapath/ResetHandler.vhd +++ b/mupix/Mupix8/sources/Datapath/ResetHandler.vhd @@ -3,18 +3,17 @@ --entities on an peripherial FPGA. --T. Weber, University Mainz ------------------------------------------------------------ - library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -entity resethandler is +entity resethandler is port ( - CLK_IN : in std_logic; -- system clock + CLK_IN : in std_logic; -- system clock RESET_IN : in std_logic; -- reset input timestampreset_out : out std_logic; -- reset FPGA timestamps eventcounterreset_out : out std_logic; -- reset FPGA event counters - -- Slave bus + -- Slave bus SLV_READ_IN : in std_logic; SLV_WRITE_IN : in std_logic; SLV_DATA_OUT : out std_logic_vector(31 downto 0); @@ -31,7 +30,7 @@ architecture behavioral of resethandler is signal eventcounterreset_i : std_logic := '0'; signal timestampreset_edge : std_logic_vector(1 downto 0) := (others => '0'); signal eventcounterreset_edge : std_logic_vector(1 downto 0) := (others => '0'); - + begin -- architecture behavioral @@ -68,7 +67,7 @@ begin -- architecture behavioral end if; end if; end process eventcounter_edge_detect; - + ------------------------------------------------------------ --TRB SLV-BUS Hanlder @@ -110,6 +109,6 @@ begin -- architecture behavioral end if; end if; end process slv_bus_handler; - + end architecture behavioral; diff --git a/mupix/Mupix8/sources/MupixBoard.vhd b/mupix/Mupix8/sources/MupixBoard.vhd index 3fad486..500080d 100644 --- a/mupix/Mupix8/sources/MupixBoard.vhd +++ b/mupix/Mupix8/sources/MupixBoard.vhd @@ -41,6 +41,7 @@ entity MupixBoard8 is spi_cs_adc : out std_logic; --load adc spi_ld_thres : out std_logic; --load threshold and injection dac hitbus : in std_logic; --hitbus signal + syncres : out std_logic; --syncres for timestamp reset mupix_data : in std_logic_vector(7 downto 0); --serdes data link from mupix channel_status_led : out std_logic_vector(3 downto 0); --status leds of serdes connection @@ -218,6 +219,8 @@ architecture Behavioral of MupixBoard8 is dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0); data_valid : out std_logic; busy : out std_logic; + eventcounter_reset : in std_logic; + timestampreset : 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); @@ -316,6 +319,16 @@ architecture Behavioral of MupixBoard8 is SLV_UNKNOWN_ADDR_OUT : out std_logic); end component MupixDataLinkWithUnpacker; + component MupixReset is + port( + mupixclk : in std_logic; + trbclk : in std_logic; + trbreset : in std_logic; + timestamp_rst : in std_logic; + syncres : out std_logic + ); + end component; + constant FIFO_DEPTH : positive := 256; --size of pseudo data generator fifos signal mux_fifo_data : std_logic_vector(c_mupixhitsize*c_links - 1 downto 0); @@ -553,6 +566,8 @@ begin -- Behavioral dataout => mupixdata_i, data_valid => mupixdata_valid_i, busy => mupixreadout_busy_i, + eventcounter_reset => eventcounterreset_in, + timestampreset => timestampreset_in, SLV_READ_IN => slv_read(3), SLV_WRITE_IN => slv_write(3), SLV_DATA_OUT => slv_data_rd(3*32 + 31 downto 3*32), @@ -647,4 +662,13 @@ begin -- Behavioral SLV_NO_MORE_DATA_OUT => slv_no_more_data(6), SLV_UNKNOWN_ADDR_OUT => slv_unknown_addr(6)); + mupix_reset: entity work.MupixReset + port map( + mupixclk => data_clk, + trbclk => clk, + trbreset => reset_reg, + timestamp_rst => timestampreset_in, + syncres => syncres + ); + end Behavioral; diff --git a/mupix/Mupix8/trb3_periph.prj b/mupix/Mupix8/trb3_periph.prj index c076d0a..9570837 100644 --- a/mupix/Mupix8/trb3_periph.prj +++ b/mupix/Mupix8/trb3_periph.prj @@ -179,6 +179,7 @@ add_file -vhdl -lib "work" "sources/Utility/HitbusHistogram.vhd" add_file -vhdl -lib "work" "sources/Utility/GrayCounter2.vhd" add_file -vhdl -lib "work" "sources/Utility/FIFO.vhd" add_file -vhdl -lib "work" "sources/Utility/CRC.vhd" +add_file -vhdl -lib "work" "sources/Utility/SignalStretcher.vhd" add_file -vhdl -lib "work" "sources/SlowControl/ADS1018SPI.vhd" add_file -vhdl -lib "work" "sources/SlowControl/LTC1658SPI.vhd" @@ -201,6 +202,7 @@ add_file -vhdl -lib "work" "sources/Datapath/DataFilter.vhd" add_file -vhdl -lib "work" "sources/Datapath/DataDecoder.vhd" add_file -vhdl -lib "work" "sources/Datapath/PixelAddressDecode.vhd" add_file -vhdl -lib "work" "sources/Datapath/Gray2Binary.vhd" +add_file -vhdl -lib "work" "sources/Datapath/MupixReset.vhd" add_file -vhdl -lib "work" "sources/Simulation/DatasourceSelector.vhd" add_file -vhdl -lib "work" "sources/Simulation/FrameGeneratorMux.vhd" diff --git a/mupix/Mupix8/trb3_periph.vhd b/mupix/Mupix8/trb3_periph.vhd index c566199..9e2f563 100644 --- a/mupix/Mupix8/trb3_periph.vhd +++ b/mupix/Mupix8/trb3_periph.vhd @@ -148,6 +148,7 @@ architecture trb3_periph_arch of trb3_periph is spi_cs_adc : out std_logic; --load adc spi_ld_thres : out std_logic; --load threshold and injection dac hitbus : in std_logic; --hitbus signal + syncres : out std_logic; mupix_data : in std_logic_vector(7 downto 0); channel_status_led : out std_logic_vector(3 downto 0); @@ -778,6 +779,7 @@ begin spi_cs_adc => spi_ld_adc, spi_ld_thres => spi_ld_thres, hitbus => hitbus, + syncres => syncres, TIMING_TRG_IN => TRIGGER_RIGHT, LVL1_TRG_DATA_VALID_IN => trg_data_valid_i, -- 2.43.0