From eb755c2fab05620d0dd66f293cd8fce1ad455b9d Mon Sep 17 00:00:00 2001 From: Adrian Weber Date: Wed, 1 Jan 2020 11:27:59 +0100 Subject: [PATCH] fix of backpressure problem in online calibration with LUT based almost Full/Empty FIFO wrapper --- .../fifoWrapper/wrapper_fifo_36_32k_oreg.vhd | 148 +++++++++++++ combiner_calib/combiner.prj | 3 + combiner_calib/combiner.vhd | 209 ++++++++++-------- 3 files changed, 267 insertions(+), 93 deletions(-) create mode 100644 combiner_calib/code_EBR/fifoWrapper/wrapper_fifo_36_32k_oreg.vhd diff --git a/combiner_calib/code_EBR/fifoWrapper/wrapper_fifo_36_32k_oreg.vhd b/combiner_calib/code_EBR/fifoWrapper/wrapper_fifo_36_32k_oreg.vhd new file mode 100644 index 0000000..1c18c37 --- /dev/null +++ b/combiner_calib/code_EBR/fifoWrapper/wrapper_fifo_36_32k_oreg.vhd @@ -0,0 +1,148 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +--use work.version.all; + + +entity wrapper_FIFO is + port( + CLK : in std_logic; + RESET : in std_logic; + DataIn : in std_logic_vector(35 downto 0); + WrEn : in std_logic; + RdEn : in std_logic; + DataOut : out std_logic_vector(35 downto 0); + DataReady : out std_logic; + AlmostEmpty : out std_logic; + AlmostFull : out std_logic +); +end entity; + +architecture arch of wrapper_FIFO is + + component fifo_36x32k_oreg + port ( + Data : in std_logic_vector(35 downto 0); + Clock : in std_logic; + WrEn : in std_logic; + RdEn : in std_logic; + Reset : in std_logic; + AmFullThresh : in std_logic_vector(14 downto 0); + Q : out std_logic_vector(35 downto 0); + WCNT : out std_logic_vector(15 downto 0); + Empty : out std_logic; + Full : out std_logic; + AlmostFull : out std_logic); + end component; + + + type FIFO_Array is array (0 to 6) of std_logic_vector(35 downto 0); --BUFFER + signal buf : FIFO_Array := (others => (others => '0')); + signal buf_alm_empty : std_logic := '0'; + signal buf_alm_full : std_logic := '0'; + signal buf_data_ready : std_logic := '0'; + signal fifo_rdEn : std_logic := '0'; + signal fifo_empty : std_logic := '0'; + signal fifo_full : std_logic := '0'; + signal fifo_data_out : std_logic_vector(35 downto 0) := (others => '0'); + + signal fifo_rdEn_r : std_logic := '0'; + signal fifo_data_ready : std_logic := '0'; + signal fifo_wcnt : std_logic_vector(15 downto 0); + signal fifo_almostFull : std_logic := '0'; + + signal fifo_empty_r : std_logic := '0'; + signal fifo_empty_d : std_logic := '0'; + +begin + + + DataOut <= buf(0); -- lowest buffer Field points to output; + DataReady <= buf_data_ready; + AlmostEmpty <= buf_alm_empty; + AlmostFull <= fifo_almostFull; + + THE_FIFO_36x32k : fifo_36x32k_oreg + port map ( + Clock => CLK, + Data => DataIn, + WrEn => WrEn, + RdEn => fifo_rdEn, + Reset => RESET, + AmFullThresh(14 downto 0) => b"111111101111111", + Q => fifo_data_out, + WCNT(15 downto 0) => fifo_wcnt, + Empty => fifo_empty, + Full => fifo_full, + AlmostFull => fifo_almostFull); + + + + THE_HANDLER : process + variable buf_wcnt : integer range 0 to 7 := 0; + begin + wait until rising_edge(CLK); + + buf_alm_empty <= '0'; + buf_alm_full <= '0'; + + if RESET = '1' then + buf_wcnt := 0; + else + --read from buffer + -- pulling RdEN to HIGH indicates, that data was taken from buffer. + -- Before, the user has to check if the data was ready! + if (RdEn = '1') and (buf_wcnt > 0) then + buf_wcnt := buf_wcnt -1; -- 0 is empty + --Move entries in buffer + buf(0) <= buf(1); + buf(1) <= buf(2); + buf(2) <= buf(3); + buf(3) <= buf(4); + buf(4) <= buf(5); + end if; + + -- write data from fifo to buffer and increment cnt of buffer fill status + if (fifo_data_ready = '1' and fifo_empty_d = '0') then + buf(buf_wcnt) <= fifo_data_out; + buf_wcnt := buf_wcnt + 1; + end if; + + -- Control of read from FIFO; Just read when almEmpty; If AlmFull then clear until almEmpty. + if (buf_wcnt >= 4) then --AlmostFull + buf_alm_full <= '1'; + fifo_rdEn <= '0'; + elsif (buf_wcnt <= 2) then --AlmostEmpty + buf_alm_empty <= '1'; + fifo_rdEn <= '1'; + end if; + + if (buf_wcnt > 0) then + buf_data_ready <= '1'; + else + buf_data_ready <= '0'; + end if; + + if (fifo_empty = '1') then + fifo_rdEn <= '0'; + end if; + end if; + end process; + + + + THE_FIFO_DATAREADY : process + begin + wait until rising_edge(CLK); + --delay of the readEnable signal + fifo_rdEn_r <= fifo_rdEn; + fifo_data_ready <= fifo_rdEn_r; + + --delay of the fifo_empty Signal to be sure the data is valid! + fifo_empty_r <= fifo_empty; + fifo_empty_d <= fifo_empty_r; + end process; + +end architecture; \ No newline at end of file diff --git a/combiner_calib/combiner.prj b/combiner_calib/combiner.prj index 7dbb571..18260da 100644 --- a/combiner_calib/combiner.prj +++ b/combiner_calib/combiner.prj @@ -64,6 +64,7 @@ add_file -vhdl -lib work "../../trbnet/gbe_trb/base/trb_net_gbe_components.vhd" #Basic Infrastructure add_file -vhdl -lib work "../cores/pll_200_100.vhd" +#add_file -vhdl -lib work "../../trb3sc/cores/pll_in200_out100.vhd" add_file -vhdl -lib work "../../trb3sc/cores/pll_in240_out200.vhd" add_file -vhdl -lib work "../../trb3sc/cores/pll_in240_out240.vhd" add_file -vhdl -lib work "../../trb3/base/cores/pll_200_4.vhd" @@ -219,6 +220,8 @@ add_file -vhdl -lib work "./code_EBR/Memory_curr.vhd" add_file -vhdl -lib work "./code_EBR/read_cnt.vhd" add_file -vhdl -lib work "./code_EBR/compare_old.vhd" add_file -vhdl -lib work "./code_EBR/Calc_output.vhd" +add_file -vhdl -lib work "./code_EBR/fifoWrapper/wrapper_fifo_36_32k_oreg.vhd" + add_file -vhdl -lib work "./core/RAM_pseudo_DP_wReg_36x1k.vhd" diff --git a/combiner_calib/combiner.vhd b/combiner_calib/combiner.vhd index 4fc4b4a..f0d6db7 100644 --- a/combiner_calib/combiner.vhd +++ b/combiner_calib/combiner.vhd @@ -191,8 +191,8 @@ architecture arch of combiner is signal cts_dataready : std_logic := '0'; signal cts_finished : std_logic; - signal pckr_fifo_full : std_logic; - signal pckr_fifo_empty : std_logic; + signal fifo_full : std_logic; + signal fifo_empty : std_logic; signal fifo_rdEn : std_logic; signal fifo_rdEn_r, fifo_rdEn_2r, fifo_rdEn_3r : std_logic; signal fifo_data_out : std_logic_vector(35 downto 0); @@ -232,6 +232,8 @@ architecture arch of combiner is signal DEBUG_read_enable_fifo_cnt2 : std_logic_vector(31 downto 0); signal Trigger_type : std_logic_vector( 3 downto 0); + + signal buf_dataready, fifo_wrapper_RdEn, fifo_wrapper_AlmostFull : std_logic := '0'; component FIFO_36x64 is port ( @@ -594,7 +596,7 @@ back_slave_ready_i <= BACK_SLAVE_READY; CTS_DATAREADY_IN => cts_dataready, CTS_READOUT_FINISHED_IN => cts_finished, CTS_READ_OUT => cts_read,--sagt, ob lese bereit - CTS_LENGTH_IN => cts_length, -- lenge der Daten ohne ertsen Header + CTS_LENGTH_IN => cts_length, -- länge der Daten ohne ersten Header CTS_STATUS_BITS_IN => MUX_cal_dout_stat, -- Data from Frontends FEE_DATA_OUT => fee_data, @@ -643,12 +645,12 @@ back_slave_ready_i <= BACK_SLAVE_READY; THE_DATAPACKER_FSM_RX : process variable sse_length_cntr : unsigned(15 downto 0) := x"0000"; variable pckr_Data_Length_Ev_cntr : unsigned(15 downto 0); - variable fpga_flag : std_logic := '0'; + variable fpga_flag : std_logic := '0'; begin wait until rising_edge(clk_sys); pckr_Data_ready <= '0'; - fee_read <= '1'; + fee_read <= not fifo_wrapper_AlmostFull; if reset_i = '1' then pckr_RX_state <= IDLE; @@ -760,7 +762,6 @@ back_slave_ready_i <= BACK_SLAVE_READY; fpga_flag := '0'; end if; pckr_Data_Length_Ev_cntr := pckr_Data_Length_Ev_cntr - 1; - -- data handling --------------------------- NON PACKING -------------- -- if sse_length_cntr = x"0000" then @@ -847,92 +848,88 @@ back_slave_ready_i <= BACK_SLAVE_READY; ----------------------------------------------------------------------- - THE_FIFO_36x32k : fifo_36x32k_oreg - port map ( - Data(31 downto 0) => MUX_cal_dout, - Data(35 downto 32) => MUX_cal_dout_type, - Clock => clk_sys, - WrEn => MUX_cal_dout_ready, - RdEn => fifo_rdEn, - Reset => reset_i, - AmFullThresh(14 downto 0) => b"011111111111111", - Q => fifo_data_out, - WCNT(15 downto 0) => WCNT_i, - Empty => pckr_fifo_empty, - Full => pckr_fifo_full, - AlmostFull => open); +-- THE_FIFO_36x32k : fifo_36x32k_oreg +-- port map ( +-- Data(31 downto 0) => MUX_cal_dout, +-- Data(35 downto 32) => MUX_cal_dout_type, +-- Clock => clk_sys, +-- WrEn => MUX_cal_dout_ready, +-- RdEn => fifo_rdEn, +-- Reset => reset_i, +-- AmFullThresh(14 downto 0) => b"011111111111111", +-- Q => fifo_data_out, +-- WCNT(15 downto 0) => WCNT_i, +-- Empty => fifo_empty, +-- Full => fifo_full, +-- AlmostFull => open); ----------------------------------------------------------------------- - THE_DATAPACKER_FSM_TX : process --data buffer is necessary - variable EvInf_TX : std_logic_vector(31 downto 0); + THE_FIFO_WRAPPER : entity work.wrapper_FIFO + port map ( + CLK => clk_sys, + RESET => reset_i, + DataIn(31 downto 0) => MUX_cal_dout, + DataIn(35 downto 32) => MUX_cal_dout_type, + WrEn => MUX_cal_dout_ready, + RdEn => fifo_wrapper_RdEn, + DataOut => fifo_data_out, + DataReady => buf_dataready, + AlmostEmpty => open, + AlmostFull => fifo_wrapper_AlmostFull); + + THE_DATAPACKER_FSM_TX : process --data buffer is necessary + variable EvInf_TX : std_logic_vector(31 downto 0); variable EvLength_TX : std_logic_vector(15 downto 0); variable EvLength_TX_cntr : unsigned(15 downto 0); variable Header_ready : std_logic:='0'; variable Data_Fifo : std_logic_vector(35 downto 0); - variable pckr_TX_data : std_logic_vector(31 downto 0); + variable pckr_TX_data : std_logic_vector(31 downto 0); variable pckr_TX_data_type : std_logic_vector( 3 downto 0); - variable buf_fifo_0 : std_logic_vector(35 downto 0); - variable buf_fifo_1 : std_logic_vector(35 downto 0); - variable buf_fifo_2 : std_logic_vector(35 downto 0); - variable buf_fifo_cnt : std_logic_vector( 1 downto 0) := "00"; - variable enable_fifo_rdEn : std_logic; + variable buf_fifo_0 : std_logic_vector(35 downto 0); + variable buf_fifo_1 : std_logic_vector(35 downto 0); + variable buf_fifo_2 : std_logic_vector(35 downto 0); + variable buf_fifo_cnt : std_logic_vector( 1 downto 0) := "00"; + variable enable_fifo_rdEn : std_logic; variable pckr_TX_data_ready : std_logic; - variable dataready : std_logic; + variable dataready : std_logic := '0'; - begin + begin wait until rising_edge(clk_sys); cts_finished <= '0'; - fifo_rdEn <= '0'; - fifo_rdEn_r <= fifo_rdEn; - fifo_rdEn_2r <= fifo_rdEn_r; --2r is readySignal - dataready := '0'; + --fifo_rdEn <= '0'; + --fifo_rdEn_r <= fifo_rdEn; + --fifo_rdEn_2r <= fifo_rdEn_r; --2r is readySignal + dataready := buf_dataready; + pckr_TX_data := fifo_data_out(31 downto 0); + pckr_TX_data_type := fifo_data_out(35 downto 32); + + fifo_wrapper_RdEn <= '0'; + --is executed if reset_i = '1' then pckr_TX_state <= EVNT; already_asked <= '0'; else - - if already_asked = '0' then - if cts_dataready = '0' then - already_asked <= '1'; - rd_enabled <= '0'; - DEBUG_read_enable_fifo_cnt <= std_logic_vector(unsigned(DEBUG_read_enable_fifo_cnt) + 1); - end if; - end if; - - if already_asked = '1' then - if pckr_fifo_empty = '0' and rd_enabled = '0' then - fifo_rdEn <= '1'; - rd_enabled <= '1'; - else - - end if; - if fifo_rdEn_2r = '1' then - dataready := '1'; - already_asked <= '0'; - DEBUG_read_enable_fifo_cnt2 <= std_logic_vector(unsigned(DEBUG_read_enable_fifo_cnt2) + 1); - pckr_TX_data := fifo_data_out(31 downto 0); - pckr_TX_data_type := fifo_data_out(35 downto 32); - end if; - end if; - - + case pckr_TX_state is when EVNT => if cts_start_readout = '1' then - if dataready = '1' then - DEBUG_read_enable_fifo_vnt1 <= std_logic_vector(unsigned(DEBUG_read_enable_fifo_vnt1) + 1); - if pckr_TX_data_type = x"1" then - --EvInf_TX := pckr_TX_data; - cts_data <= pckr_TX_data; - end if; --maybe a flag that x"1" is set before x"2" comes? - - if pckr_TX_data_type = x"2" then - cts_length <= pckr_TX_data(31 downto 16); - EvLength_TX_cntr := pckr_TX_data(31 downto 16); - Header_ready := '1'; + if Header_ready = '0' then + if dataready = '1' and fifo_wrapper_RdEn = '0' then --new data is ready at FIFO wrapper + DEBUG_read_enable_fifo_vnt1 <= std_logic_vector(unsigned(DEBUG_read_enable_fifo_vnt1) + 1); + fifo_wrapper_RdEn <= '1'; + if pckr_TX_data_type = x"1" then + --EvInf_TX := pckr_TX_data; + cts_data <= pckr_TX_data; + end if; --maybe a flag that x"1" is set before x"2" comes? + + if pckr_TX_data_type = x"2" then + cts_length <= pckr_TX_data(31 downto 16); + EvLength_TX_cntr := pckr_TX_data(31 downto 16); + Header_ready := '1'; + end if; end if; end if; --cts_data <= EvInf_TX; @@ -952,24 +949,28 @@ back_slave_ready_i <= BACK_SLAVE_READY; when DATA => - if pckr_TX_data_type = x"3" or pckr_TX_data_type = x"4" or pckr_TX_data_type = x"5" then - if dataready = '1' then - cts_data <= pckr_TX_data; - cts_dataready <= '1'; - end if; + if cts_start_readout = '1' then + if pckr_TX_data_type = x"3" or pckr_TX_data_type = x"4" or pckr_TX_data_type = x"5" then + --TODO: check if this is correct -> Maybe faster, if read signal in wrapper_fifo is async + if dataready = '1' and fifo_wrapper_RdEn = '0' then-- maybe without fifo_wrapper_RdEn, but like this it is more safe, but also slower + cts_data <= pckr_TX_data; + cts_dataready <= '1'; + end if; + --TODO: check if this is correct + if cts_read = '1' and cts_dataready = '1' then + fifo_wrapper_RdEn <= '1'; + EvLength_TX_cntr := EvLength_TX_cntr - 1; + cts_dataready <= '0'; + end if; - if cts_read = '1' and cts_dataready = '1' then - EvLength_TX_cntr := EvLength_TX_cntr - 1; - cts_dataready <= '0'; - end if; - - if EvLength_TX_cntr = 0 then - pckr_TX_state <= FINISH; - cts_dataready <= '0'; + if EvLength_TX_cntr = 0 then + pckr_TX_state <= FINISH; + cts_dataready <= '0'; + end if; end if; + DEBUG_EvtLength <= EvLength_TX_cntr; + FSM_state_TX <= x"00000002"; end if; - DEBUG_EvtLength <= EvLength_TX_cntr; - FSM_state_TX <= x"00000002"; when FINISH => cts_finished <= '1'; @@ -986,7 +987,32 @@ back_slave_ready_i <= BACK_SLAVE_READY; end if; end process; - + +-- sbuf for fix of statemachine ? +-- THE_SBUF : work.trb_net_sbuf is +-- generic map ( +-- DATA_WIDTH <= 36 +-- ) +-- port map ( +-- -- Misc +-- CLK <= sys_clk, +-- RESET <= reset_i, +-- CLK_EN <= '1'. +-- -- port to combinatorial logic +-- COMB_DATAREADY_IN <= cts_dataready, +-- COMB_next_READ_OUT <= , +-- COMB_READ_IN <=, +-- -- the COMB_next_READ_OUT should be connected via comb. logic to a register +-- -- to provide COMB_READ_IN (feedback path with 1 cycle delay) +-- COMB_DATA_IN <=, +-- -- Port to synchronous output. +-- SYN_DATAREADY_OUT <=, +-- SYN_DATA_OUT <=, +-- SYN_READ_IN <=, +-- -- Status and control port +-- DEBUG_OUT <= open, +-- STAT_BUFFER <= open +-- ); --------------------------------------------------------------------------- @@ -1039,9 +1065,9 @@ back_slave_ready_i <= BACK_SLAVE_READY; busdebug_tx.data <= FSM_state_TX; end if; if busdebug_rx.addr(7 downto 0) = x"02" then - busdebug_tx.data(0) <= pckr_fifo_empty; + busdebug_tx.data(0) <= fifo_empty; busdebug_tx.data(3 downto 1) <= (others => '0'); - busdebug_tx.data(4) <= pckr_fifo_full; + busdebug_tx.data(4) <= fifo_full; busdebug_tx.data(15 downto 5) <= (others => '0'); busdebug_tx.data(31 downto 16) <= WCNT_i; end if; @@ -1254,7 +1280,4 @@ back_slave_ready_i <= BACK_SLAVE_READY; spi_miso(6) <= POWER_BOARD_IO(4); -end architecture; - - - +end architecture; \ No newline at end of file -- 2.43.0