From df29e19f6dade0c5c281ac390c5f746b63556140 Mon Sep 17 00:00:00 2001 From: Oliver Bruendler Date: Thu, 7 Nov 2019 07:46:37 +0100 Subject: [PATCH] TIMING: Optimized timing on critical path between input FIFO and DMA Added pipeline stage after FIFO to reduce requirements of fall-through interface --- hdl/psi_ms_daq_input.vhd | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/hdl/psi_ms_daq_input.vhd b/hdl/psi_ms_daq_input.vhd index 1ba9ebf..4c7572f 100644 --- a/hdl/psi_ms_daq_input.vhd +++ b/hdl/psi_ms_daq_input.vhd @@ -114,6 +114,11 @@ architecture rtl of psi_ms_daq_input is signal DataFifo_InRdy : std_logic; signal DataFifo_InData : std_logic_vector(69 downto 0); signal DataFifo_OutData : std_logic_vector(69 downto 0); + signal DataFifo_PlData : std_logic_vector(69 downto 0); + signal DataFifo_PlVld : std_logic; + signal DataFifo_PlRdy : std_logic; + signal DataFifo_Level : std_logic_vector(log2ceil(StreamBuffer_g) downto 0); + signal DataPl_Level : unsigned(1 downto 0); -- Internally reused signals signal Daq_Data_I : Input2Daq_Data_t; @@ -343,6 +348,7 @@ begin -- Output Side TLAST handling -------------------------------------------- p_outlast : process(ClkMem) + variable PlLevel_v : unsigned(DataPl_Level'range); begin if rising_edge(ClkMem) then -- Default Value @@ -357,11 +363,26 @@ begin if OutTlastCnt /= InTlastCnt then Daq_HasLast_I <= '1'; end if; + + -- Level Calculation (add samples in PL stage) + PlLevel_v := DataPl_Level; + if DataFifo_PlRdy = '1' and DataFifo_PlVld = '1' then + PlLevel_v := PlLevel_v + 1; + end if; + if Daq_Vld_I = '1' and Daq_Rdy = '1' then + PlLevel_v := PlLevel_v - 1; + end if; + DataPl_Level <= PlLevel_v; + -- We calculate the level one cycle late but this does not play any role (the DAQ FSM only runs after data is transferred) + Daq_Level <= std_logic_vector(resize(unsigned(DataFifo_Level), Daq_Level'length) + DataPl_Level); -- Reset if RstMem = '1' then - OutTlastCnt <= (others => '0'); - end if; + OutTlastCnt <= (others => '0'); + Daq_Level <= (others => '0'); + DataPl_Level <= (others => '0'); + end if; + end if; end process; Daq_HasLast <= Daq_HasLast_I; @@ -455,8 +476,8 @@ begin -- Data FIFO DataFifo_InData(63 downto 0) <= r.DataSftReg; DataFifo_InData(67 downto 64) <= std_logic_vector(r.DataFifoBytes); - DataFifo_InData(68) <= r.DataFifoIsTo; - DataFifo_InData(69) <= r.DataFifoIsTrig; + DataFifo_InData(68) <= r.DataFifoIsTo; + DataFifo_InData(69) <= r.DataFifoIsTrig; i_dfifo : entity work.psi_common_async_fifo @@ -474,12 +495,28 @@ begin InData => DataFifo_InData, InVld => r.DataFifoVld, InRdy => DataFifo_InRdy, - OutData => DataFifo_OutData, - OutVld => Daq_Vld_I, - OutRdy => Daq_Rdy, - OutLevel => Daq_Level(log2ceil(StreamBuffer_g) downto 0) + OutData => DataFifo_PlData, + OutVld => DataFifo_PlVld, + OutRdy => DataFifo_PlRdy, + OutLevel => DataFifo_Level + ); + + -- An additional pipeline stage after the FIFO is required for timing reasons + i_dplstage : entity work.psi_common_pl_stage + generic map ( + Width_g => 70, + UseRdy_g => true + ) + port map ( + Clk => ClkMem, + Rst => RstMem, + InVld => DataFifo_PlVld, + InRdy => DataFifo_PlRdy, + InData => DataFifo_PlData, + OutVld => Daq_Vld_I, + OutRdy => Daq_Rdy, + OutData => DataFifo_OutData ); - Daq_Level(Daq_Level'high downto log2ceil(StreamBuffer_g)+1) <= (others => '0'); Str_Rdy <= DataFifo_InRdy; Daq_Data_I.Data <= DataFifo_OutData(63 downto 0);