From 068719a36bd3f4ac3aab897ba5a61c388869f810 Mon Sep 17 00:00:00 2001 From: Ludwig Maier Date: Sun, 15 Dec 2013 12:58:21 +0100 Subject: [PATCH] nxyter working design --- nxyter/cores/ram_dp_128x32.ipx | 12 +- nxyter/cores/ram_dp_128x32.lpc | 6 +- nxyter/cores/ram_dp_128x32.vhd | 6 +- nxyter/source/debug_multiplexer.vhd | 13 +- nxyter/source/nx_data_receiver.vhd | 15 -- nxyter/source/nx_histogram.vhd | 254 ++++++++++++------------- nxyter/source/nx_histograms.vhd | 7 +- nxyter/source/nx_trigger_validate.vhd | 262 +++++++++++++++++++++----- nxyter/source/registers.txt | 11 +- 9 files changed, 368 insertions(+), 218 deletions(-) diff --git a/nxyter/cores/ram_dp_128x32.ipx b/nxyter/cores/ram_dp_128x32.ipx index b098730..d4b9690 100644 --- a/nxyter/cores/ram_dp_128x32.ipx +++ b/nxyter/cores/ram_dp_128x32.ipx @@ -1,10 +1,10 @@ - + - - - - - + + + + + diff --git a/nxyter/cores/ram_dp_128x32.lpc b/nxyter/cores/ram_dp_128x32.lpc index 9a279f3..b6dcd6e 100644 --- a/nxyter/cores/ram_dp_128x32.lpc +++ b/nxyter/cores/ram_dp_128x32.lpc @@ -16,8 +16,8 @@ CoreRevision=6.1 ModuleName=ram_dp_128x32 SourceFormat=VHDL ParameterFileVersion=1.0 -Date=11/30/2013 -Time=22:39:02 +Date=12/13/2013 +Time=22:59:16 [Parameters] Verilog=0 @@ -35,7 +35,7 @@ enByte=0 ByteSize=9 adPipeline=0 inPipeline=0 -outPipeline=1 +outPipeline=0 MOR=0 InData=Registered AdControl=Registered diff --git a/nxyter/cores/ram_dp_128x32.vhd b/nxyter/cores/ram_dp_128x32.vhd index 7cd3202..802e3f3 100644 --- a/nxyter/cores/ram_dp_128x32.vhd +++ b/nxyter/cores/ram_dp_128x32.vhd @@ -1,8 +1,8 @@ -- VHDL netlist generated by SCUBA Diamond_2.1_Production (100) -- Module Version: 6.1 ---/usr/local/opt/lattice_diamond/diamond/2.1/ispfpga/bin/lin64/scuba -w -lang vhdl -synth synplify -bus_exp 7 -bb -arch ep5c00 -type bram -wp 10 -rp 0011 -rdata_width 32 -data_width 32 -num_rows 128 -outdata REGISTERED -cascade -1 -e +--/usr/local/opt/lattice_diamond/diamond/2.1/ispfpga/bin/lin64/scuba -w -lang vhdl -synth synplify -bus_exp 7 -bb -arch ep5c00 -type bram -wp 10 -rp 0011 -rdata_width 32 -data_width 32 -num_rows 128 -cascade -1 -e --- Sat Nov 30 22:39:02 2013 +-- Fri Dec 13 22:59:16 2013 library IEEE; use IEEE.std_logic_1164.all; @@ -113,7 +113,7 @@ begin ram_dp_128x32_0_0_0: PDPW16KC generic map (CSDECODE_R=> "0b000", CSDECODE_W=> "0b001", GSR=> "DISABLED", - REGMODE=> "OUTREG", DATA_WIDTH_R=> 36, DATA_WIDTH_W=> 36) + REGMODE=> "NOREG", DATA_WIDTH_R=> 36, DATA_WIDTH_W=> 36) port map (DI0=>Data(0), DI1=>Data(1), DI2=>Data(2), DI3=>Data(3), DI4=>Data(4), DI5=>Data(5), DI6=>Data(6), DI7=>Data(7), DI8=>Data(8), DI9=>Data(9), DI10=>Data(10), DI11=>Data(11), diff --git a/nxyter/source/debug_multiplexer.vhd b/nxyter/source/debug_multiplexer.vhd index a80d6e6..21df593 100644 --- a/nxyter/source/debug_multiplexer.vhd +++ b/nxyter/source/debug_multiplexer.vhd @@ -45,9 +45,16 @@ begin DEBUG_LINE_IN) begin if (unsigned(port_select) < NUM_PORTS) then - debug_line_o <= DEBUG_LINE_IN(to_integer(unsigned(port_select))); + debug_line_o <= + DEBUG_LINE_IN(to_integer(unsigned(port_select))); + elsif (unsigned(port_select) = NUM_PORTS) then + -- Checkerboard + for I in 0 to 7 loop + debug_line_o(I * 2) <= CLK_IN; + debug_line_o(I * 2 + 1) <= not CLK_IN; + end loop; else - debug_line_o <= (others => '1'); + debug_line_o <= (others => '1'); end if; end process PROC_MULTIPLEXER; @@ -69,7 +76,7 @@ begin if (SLV_WRITE_IN = '1') then case SLV_ADDR_IN is when x"0000" => - if (unsigned(SLV_DATA_IN(7 downto 0)) < NUM_PORTS) then + if (unsigned(SLV_DATA_IN(7 downto 0)) < NUM_PORTS + 1) then port_select <= SLV_DATA_IN(7 downto 0); end if; slv_ack_o <= '1'; diff --git a/nxyter/source/nx_data_receiver.vhd b/nxyter/source/nx_data_receiver.vhd index dd41a1f..dbe31df 100644 --- a/nxyter/source/nx_data_receiver.vhd +++ b/nxyter/source/nx_data_receiver.vhd @@ -848,21 +848,6 @@ begin end if; end process PROC_NX_FIFO_READ; - PROC_NX_FIFO_DELAY: process(CLK_IN) - begin - if (rising_edge(CLK_IN) ) then - if (RESET_IN = '1' or fifo_reset_r = '1') then - - else - if (nx_fifo_data_valid = '1') then - - else - - end if; - end if; - end if; - end process PROC_NX_FIFO_DELAY; - ----------------------------------------------------------------------------- -- Status Counters ----------------------------------------------------------------------------- diff --git a/nxyter/source/nx_histogram.vhd b/nxyter/source/nx_histogram.vhd index fab21ac..f8549ee 100644 --- a/nxyter/source/nx_histogram.vhd +++ b/nxyter/source/nx_histogram.vhd @@ -33,52 +33,71 @@ end entity; architecture Behavioral of nx_histogram is - -- Read Handler - type R_STATES is (R_IDLE, - R_WAIT, - R_READ + -- Hist Fill/Ctr Handler + type H_STATES is (H_IDLE, + H_WRITE_CHANNEL ); - signal R_STATE, R_NEXT_STATE : R_STATES; - - signal read_data : std_logic_vector(DATA_WIDTH - 1 downto 0); - signal read_address : std_logic_vector(BUS_WIDTH - 1 downto 0); - signal read_address_f : std_logic_vector(BUS_WIDTH - 1 downto 0); - signal read_enable : std_logic; - signal channel_data_o : std_logic_vector(DATA_WIDTH - 1 downto 0); - signal channel_data_valid_o : std_logic; - signal channel_read_busy_o : std_logic; - - -- Write Handler - type W_STATES is (W_IDLE, - W_WRITE, - W_ADD - ); - signal W_STATE, W_NEXT_STATE : W_STATES; - - signal write_address : std_logic_vector(BUS_WIDTH - 1 downto 0); - signal write_address_f : std_logic_vector(BUS_WIDTH - 1 downto 0); - signal write_data : std_logic_vector(DATA_WIDTH - 1 downto 0); - signal write_data_f : std_logic_vector(DATA_WIDTH - 1 downto 0); - signal write_enable : std_logic; - signal channel_write_busy_o : std_logic; + signal H_STATE, H_NEXT_STATE : H_STATES; + + signal address_hist_m : std_logic_vector(6 downto 0); + signal address_hist_m_x : std_logic_vector(6 downto 0); + signal data_hist_m : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal data_hist_m_x : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal read_data_hist : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal read_address_hist : std_logic_vector(BUS_WIDTH - 1 downto 0); + signal read_enable_hist : std_logic; + + signal write_address_hist : std_logic_vector(BUS_WIDTH - 1 downto 0); + signal write_data_hist : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal write_enable_hist : std_logic; + + signal write_address : std_logic_vector(BUS_WIDTH - 1 downto 0); + signal write_data : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal write_enable : std_logic; + + signal channel_write_busy_o : std_logic; + + -- Hist Read Handler + signal read_address : std_logic_vector(BUS_WIDTH - 1 downto 0); + signal read_data : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal read_enable : std_logic; + signal channel_data_o : std_logic_vector(DATA_WIDTH - 1 downto 0); + signal channel_data_valid_o : std_logic; + signal channel_data_valid_o_f : std_logic; + signal channel_read_busy_o : std_logic; + begin ----------------------------------------------------------------------------- DEBUG_OUT(0) <= CLK_IN; DEBUG_OUT(1) <= channel_write_busy_o; - DEBUG_OUT(2) <= CHANNEL_WRITE_IN; - DEBUG_OUT(3) <= write_enable; + DEBUG_OUT(2) <= CHANNEL_ADD_IN; + DEBUG_OUT(3) <= write_enable_hist; DEBUG_OUT(4) <= channel_read_busy_o; DEBUG_OUT(5) <= CHANNEL_READ_IN; - DEBUG_OUT(6) <= read_enable; + DEBUG_OUT(6) <= read_enable_hist; DEBUG_OUT(7) <= channel_data_valid_o; - DEBUG_OUT(15 downto 8) <= read_data(7 downto 0); + DEBUG_OUT(15 downto 8) <= channel_data_o(7 downto 0); ----------------------------------------------------------------------------- - ram_dp_128x32_1: ram_dp_128x32 + ram_dp_128x32_hist: ram_dp_128x32 + port map ( + WrAddress => write_address_hist, + RdAddress => read_address_hist, + Data => write_data_hist, + WE => not RESET_IN, + RdClock => CLK_IN, + RdClockEn => read_enable_hist, + Reset => RESET_IN, + WrClock => CLK_IN, + WrClockEn => write_enable_hist, + Q => read_data_hist + ); + + ram_dp_128x32_result: ram_dp_128x32 port map ( WrAddress => write_address, RdAddress => read_address, @@ -95,117 +114,92 @@ begin ----------------------------------------------------------------------------- -- Memory Handler ----------------------------------------------------------------------------- - PROC_MEM_HANDLER_TRANSFER: process(CLK_IN) + + pulse_to_level_1: pulse_to_level + generic map ( + NUM_CYCLES => 3 + ) + port map ( + CLK_IN => CLK_IN, + RESET_IN => RESET_IN, + PULSE_IN => read_enable, + LEVEL_OUT => channel_read_busy_o + ); + + read_enable <= CHANNEL_READ_IN; + read_address <= CHANNEL_ID_READ_IN; + channel_data_valid_o_f <= CHANNEL_READ_IN when rising_edge(CLK_IN); + channel_data_valid_o <= channel_data_valid_o_f when rising_edge(CLK_IN); + channel_data_o <= read_data when rising_edge(CLK_IN); + + PROC_HIST_HANDLER_TRANSFER: process(CLK_IN) begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then - read_address_f <= (others => '0'); - R_STATE <= R_IDLE; - - write_address_f <= (others => '0'); - write_data_f <= (others => '0'); - W_STATE <= W_IDLE; + address_hist_m <= (others => '0'); + data_hist_m <= (others => '0'); + H_STATE <= H_IDLE; else - read_address_f <= read_address; - R_STATE <= R_NEXT_STATE; - - write_address_f <= write_address; - write_data_f <= write_data; - W_STATE <= W_NEXT_STATE; + address_hist_m <= address_hist_m_x; + data_hist_m <= data_hist_m_x; + H_STATE <= H_NEXT_STATE; end if; end if; - end process PROC_MEM_HANDLER_TRANSFER; - - PROC_MEM_HANDLER: process(R_STATE, - CHANNEL_ID_READ_IN, - CHANNEL_READ_IN - ) + end process PROC_HIST_HANDLER_TRANSFER; + + PROC_HIST_HANDLER: process(H_STATE, + CHANNEL_ID_IN, + CHANNEL_DATA_IN, + CHANNEL_ADD_IN, + CHANNEL_WRITE_IN + ) + variable new_data : unsigned(31 downto 0); begin - case R_STATE is - when R_IDLE => - channel_data_o <= (others => '0'); - channel_data_valid_o <= '0'; - - if (CHANNEL_READ_IN = '1') then - read_address <= CHANNEL_ID_READ_IN; - if (CHANNEL_ADD_IN = '1') then - read_enable <= '0'; - channel_read_busy_o <= '0'; - R_NEXT_STATE <= R_WAIT; - else - read_enable <= '1'; - channel_read_busy_o <= '1'; - R_NEXT_STATE <= R_READ; - end if; - else - read_address <= (others => '0'); - read_enable <= '0'; - channel_read_busy_o <= '0'; - R_NEXT_STATE <= R_IDLE; - end if; - - when R_WAIT => - read_address <= read_address_f; - if (channel_read_busy_o = '0') then - channel_read_busy_o <= '1'; - read_enable <= '1'; - R_NEXT_STATE <= R_READ; - else - read_enable <= '0'; - R_NEXT_STATE <= R_WAIT; - end if; - - when R_READ => - read_address <= (others => '0'); - read_enable <= '0'; - channel_read_busy_o <= '1'; - channel_data_o <= read_data; - channel_data_valid_o <= '1'; - R_NEXT_STATE <= R_IDLE; - - end case; - - case W_STATE is - when W_IDLE => - if (CHANNEL_WRITE_IN = '1') then - write_address <= CHANNEL_ID_IN; - write_data <= CHANNEL_DATA_IN; - write_enable <= '1'; - channel_write_busy_o <= '1'; - W_NEXT_STATE <= W_WRITE; - elsif (CHANNEL_ADD_IN = '1') then - read_address <= CHANNEL_ID_IN; - read_enable <= '1'; - write_address <= CHANNEL_ID_IN; - write_data <= CHANNEL_DATA_IN; - channel_read_busy_o <= '1'; + address_hist_m_x <= address_hist_m; + data_hist_m_x <= data_hist_m; + + case H_STATE is + when H_IDLE => + write_address_hist <= (others => '0'); + write_data_hist <= (others => '0'); + write_enable_hist <= '0'; + write_address <= (others => '0'); + write_data <= (others => '0'); + write_enable <= '0'; + + if (CHANNEL_ADD_IN = '1') then + read_address_hist <= CHANNEL_ID_IN; + read_enable_hist <= '1'; + address_hist_m_x <= CHANNEL_ID_IN; + data_hist_m_x <= CHANNEL_DATA_IN; channel_write_busy_o <= '1'; - W_NEXT_STATE <= W_ADD; + H_NEXT_STATE <= H_WRITE_CHANNEL; else - write_address <= (others => '0'); - write_data <= (others => '0'); - write_enable <= '0'; + read_address_hist <= (others => '0'); + read_enable_hist <= '0'; + address_hist_m_x <= (others => '0'); + data_hist_m_x <= (others => '0'); channel_write_busy_o <= '0'; - W_NEXT_STATE <= W_IDLE; - end if; - - when W_ADD => - write_address <= write_address_f; - write_data <= - std_logic_vector(unsigned(read_data) + unsigned(write_data_f)); + H_NEXT_STATE <= H_IDLE; + end if; + + when H_WRITE_CHANNEL => + new_data := + std_logic_vector(unsigned(read_data_hist) + unsigned(data_hist_m)); + read_address_hist <= (others => '0'); + read_enable_hist <= '0'; + write_address_hist <= address_hist_m; + write_data_hist <= new_data; + write_enable_hist <= '1'; + + write_address <= address_hist_m; + write_data <= new_data; write_enable <= '1'; channel_write_busy_o <= '1'; - W_NEXT_STATE <= W_WRITE; - - when W_WRITE => - write_address <= (others => '0'); - write_data <= (others => '0'); - write_enable <= '0'; - channel_write_busy_o <= '1'; - W_NEXT_STATE <= W_IDLE; - + H_NEXT_STATE <= H_IDLE; end case; - end process PROC_MEM_HANDLER; + + end process PROC_HIST_HANDLER; ----------------------------------------------------------------------------- -- Output Signals diff --git a/nxyter/source/nx_histograms.vhd b/nxyter/source/nx_histograms.vhd index fe73ac1..7a0f1e2 100644 --- a/nxyter/source/nx_histograms.vhd +++ b/nxyter/source/nx_histograms.vhd @@ -141,11 +141,10 @@ begin if (hist_read_busy = '1') then if (hist_read_data_valid = '1') then - slv_data_out_o(11 downto 0) <= hist_read_data(11 downto 0); - slv_data_out_o(31 downto 12) <= (others => '0'); - slv_ack_o <= '1'; + slv_data_out_o <= hist_read_data; + slv_ack_o <= '1'; else - slv_ack_o <= '0'; + slv_ack_o <= '0'; end if; elsif (SLV_READ_IN = '1') then diff --git a/nxyter/source/nx_trigger_validate.vhd b/nxyter/source/nx_trigger_validate.vhd index 05f7094..3dd6e32 100644 --- a/nxyter/source/nx_trigger_validate.vhd +++ b/nxyter/source/nx_trigger_validate.vhd @@ -59,52 +59,70 @@ end entity; architecture Behavioral of nx_trigger_validate is -- Process Channel_Status - signal channel_index : std_logic_vector(6 downto 0); - signal channel_wait : std_logic_vector(127 downto 0); - signal channel_done : std_logic_vector(127 downto 0); - signal channel_hit : std_logic_vector(127 downto 0); - signal channel_all_done : std_logic; + signal channel_index : std_logic_vector(6 downto 0); + signal channel_wait : std_logic_vector(127 downto 0); + signal channel_done : std_logic_vector(127 downto 0); + signal channel_hit : std_logic_vector(127 downto 0); + signal channel_all_done : std_logic; - signal channel_done_r : std_logic_vector(127 downto 0); - signal channel_wait_r : std_logic_vector(127 downto 0); - signal channel_hit_r : std_logic_vector(127 downto 0); - signal channel_all_done_r : std_logic; - signal token_update : std_logic; + signal channel_done_r : std_logic_vector(127 downto 0); + signal channel_wait_r : std_logic_vector(127 downto 0); + signal channel_hit_r : std_logic_vector(127 downto 0); + signal channel_all_done_r : std_logic; + signal token_update : std_logic; -- Channel Status Commands type CS_CMDS is (CS_RESET, + CS_CLEAR_WAIT, CS_TOKEN_UPDATE, CS_SET_WAIT, CS_SET_HIT, CS_SET_DONE, CS_NONE ); - signal channel_status_cmd : CS_CMDS; + signal channel_status_cmd : CS_CMDS; -- Process Calculate Trigger Window - signal fifo_delay_time : unsigned(11 downto 0); + signal fifo_delay_time : unsigned(11 downto 0); -- Process Timestamp - signal d_data_o : std_logic_vector(31 downto 0); - signal d_data_clk_o : std_logic; - signal out_of_window_l : std_logic; - signal out_of_window_h : std_logic; - signal out_of_window_error : std_logic; - signal ch_status_cmd_pr : CS_CMDS; - + signal d_data_o : std_logic_vector(31 downto 0); + signal d_data_clk_o : std_logic; + signal out_of_window_l : std_logic; + signal out_of_window_h : std_logic; + signal window_hit : std_logic; + signal out_of_window_error : std_logic; + signal ch_status_cmd_pr : CS_CMDS; + + -- Window Status Counter + signal out_of_window_l_ctr : unsigned(15 downto 0); + signal window_hit_ctr : unsigned(15 downto 0); + signal out_of_window_h_ctr : unsigned(15 downto 0); + signal out_of_window_l_ctr_r : unsigned(15 downto 0); + signal window_hit_ctr_r : unsigned(15 downto 0); + signal out_of_window_h_ctr_r : unsigned(15 downto 0); + signal validation_busy : std_logic_vector(1 downto 0); + + -- Rate Calculations + signal data_rate_ctr : unsigned(27 downto 0); + signal data_rate : unsigned(27 downto 0); + signal rate_timer_ctr : unsigned(27 downto 0); + -- Self Trigger Mode - signal self_trigger_mode : std_logic; + signal self_trigger_mode : std_logic; -- Process Trigger Handler - signal store_to_fifo : std_logic; - signal trigger_busy_o : std_logic; - signal nomore_data_o : std_logic; - signal wait_timer_init : unsigned(11 downto 0); - signal wait_timer_init_ns : unsigned(19 downto 0); - signal token_return_last : std_logic; - signal token_return_first : std_logic; - signal ch_status_cmd_tr : CS_CMDS; - signal wait_for_data_time_r : std_logic_vector(19 downto 0); + signal store_to_fifo : std_logic; + signal trigger_busy_o : std_logic; + signal nomore_data_o : std_logic; + signal wait_timer_init : unsigned(11 downto 0); + signal wait_timer_init_ns : unsigned(19 downto 0); + signal token_return_last : std_logic; + signal token_return_first : std_logic; + signal ch_status_cmd_tr : CS_CMDS; + signal wait_for_data_time_r : std_logic_vector(19 downto 0); + signal min_validation_time_r : std_logic_vector(19 downto 0); + signal skip_wait_for_data : std_logic; type STATES is (S_TEST_SELF_TRIGGER, S_IDLE, @@ -159,7 +177,7 @@ architecture Behavioral of nx_trigger_validate is signal out_of_window_error_ctr_clear : std_logic; -- Timestamp Trigger Window Settings - constant nxyter_cv_time : unsigned(11 downto 0) := x"190"; -- 400ns + signal nxyter_cv_time : unsigned(11 downto 0); signal cts_trigger_delay : unsigned(11 downto 0); signal ts_window_offset : signed(11 downto 0); signal ts_window_width : unsigned(9 downto 0); @@ -232,6 +250,7 @@ begin d_data_clk_o <= '0'; out_of_window_l <= '0'; out_of_window_h <= '0'; + window_hit <= '0'; out_of_window_error <= '0'; fifo_delay_time <= (others => '0'); out_of_window_error_ctr <= (others => '0'); @@ -240,6 +259,7 @@ begin d_data_clk_o <= '0'; out_of_window_l <= '0'; out_of_window_h <= '0'; + window_hit <= '0'; out_of_window_error <= '0'; fifo_delay_time <= (others => '0'); ch_status_cmd_pr <= CS_NONE; @@ -289,7 +309,7 @@ begin if (DATA_CLK_IN = '1') then if (store_to_fifo = '1' and EVT_BUFFER_FULL_IN = '0') then - store_data := '0'; + store_data := '0'; -- TS Window Check if (ts_window_check_value(11) = '1') then @@ -309,6 +329,7 @@ begin -- TS in between Window: Set WAIT Bit in LUT and Take Data channel_index <= CHANNEL_IN; ch_status_cmd_pr <= CS_SET_HIT; + window_hit <= '1'; store_data := '1'; else -- TS Window Error condition, do nothing @@ -372,6 +393,83 @@ begin end if; end process PROC_FILTER_TIMESTAMPS; + PROC_WINDOW_STATE_CTR: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + out_of_window_l_ctr <= (others => '0'); + window_hit_ctr <= (others => '0'); + out_of_window_h_ctr <= (others => '0'); + out_of_window_l_ctr_r <= (others => '0'); + window_hit_ctr_r <= (others => '0'); + out_of_window_h_ctr_r <= (others => '0'); + validation_busy <= (others => '0'); + else + validation_busy(0) <= store_to_fifo; + validation_busy(1) <= validation_busy(0); + + case validation_busy is + when "00"=> -- No validation + out_of_window_l_ctr <= (others => '0'); + window_hit_ctr <= (others => '0'); + out_of_window_l_ctr <= (others => '0'); + + when "01"=> -- Start validation + out_of_window_l_ctr <= (others => '0'); + window_hit_ctr <= (others => '0'); + out_of_window_l_ctr <= (others => '0'); + + when "10"=> -- End validation + out_of_window_l_ctr_r <= out_of_window_l_ctr; + window_hit_ctr_r <= window_hit_ctr; + out_of_window_l_ctr_r <= out_of_window_l_ctr; + + when "11" => -- Validation + if (out_of_window_l = '1') then + out_of_window_l_ctr <= out_of_window_l_ctr + 1; + end if; + + if (window_hit = '1') then + window_hit_ctr <= window_hit_ctr + 1; + end if; + + if (out_of_window_l = '1') then + out_of_window_h_ctr <= out_of_window_h_ctr + 1; + end if; + + end case; + end if; + end if; + end process PROC_WINDOW_STATE_CTR; + + PROC_RATE_COUNTER: process(CLK_IN) + begin + if (rising_edge(CLK_IN) ) then + if (RESET_IN = '1') then + data_rate_ctr <= (others => '0'); + data_rate <= (others => '0'); + rate_timer_ctr <= (others => '0'); + else + if (rate_timer_ctr < x"5f5e100") then + rate_timer_ctr <= rate_timer_ctr + 1; + + if (d_data_clk_o = '1') then + data_rate_ctr <= data_rate_ctr + 1; + end if; + else + rate_timer_ctr <= (others => '0'); + data_rate <= data_rate_ctr; + + if (d_data_clk_o = '0') then + data_rate_ctr <= (others => '0'); + else + data_rate_ctr <= x"000_0001"; + end if; + end if; + end if; + end if; + end process PROC_RATE_COUNTER; + ----------------------------------------------------------------------------- -- Trigger Handler ----------------------------------------------------------------------------- @@ -420,6 +518,7 @@ begin timestamp_ref <= (others => '0'); evt_buffer_clear_o <= '0'; wait_for_data_time_r <= (others => '0'); + min_validation_time_r <= (others => '0'); STATE <= S_TEST_SELF_TRIGGER; else store_to_fifo <= '0'; @@ -432,24 +531,36 @@ begin t_data_clk_o <= '0'; ch_status_cmd_tr <= CS_NONE; evt_buffer_clear_o <= '0'; - + + -- Wait for Data and minimum Validation Time calculation + min_validation_time := resize(ts_window_width * 4, 20); wait_for_data_time := - resize(nxyter_cv_time, 20) + data_fifo_delay_o * 32; - --wait_for_data_time := x"00008"; - min_validation_time := resize(ts_window_width * 4, 20); + resize(nxyter_cv_time, 20) + data_fifo_delay_o * 32 + 320; + + if (skip_wait_for_data = '1') then + min_validation_time := + min_validation_time + wait_for_data_time; + wait_for_data_time := x"00001"; + end if; + min_validation_time_r <= min_validation_time; wait_for_data_time_r <= wait_for_data_time; - + -- Check Token Return token_return_last <= NX_TOKEN_RETURN_IN; - if (store_to_fifo = '1' and + if (store_to_fifo = '1' and -- min_val_time handled by TK-UPDATE NX_TOKEN_RETURN_IN = '1' and token_return_last = '0') then - if (token_return_first = '1') then - ch_status_cmd_tr <= CS_TOKEN_UPDATE; + if (min_val_time_expired = '1') then + if (token_return_first = '1') then + ch_status_cmd_tr <= CS_TOKEN_UPDATE; + else + token_return_first <= '1'; + ch_status_cmd_tr <= CS_CLEAR_WAIT; + end if; else - token_return_first <= '1'; - end if; - end if; + ch_status_cmd_tr <= CS_CLEAR_WAIT; + end if; + end if; case STATE is @@ -490,7 +601,7 @@ begin when S_TRIGGER => if (self_trigger_mode = '0') then readout_mode <= readout_mode_r; - + -- wait for data arrival and clear evt buffer wait_timer_init_ns <= wait_for_data_time; evt_buffer_clear_o <= '1'; @@ -568,7 +679,7 @@ begin end if; when S_WRITE_TRAILER => - state_d <= "11"; + state_d <= "11"; t_data_o <= (others => '1'); t_data_clk_o <= '1'; STATE <= S_SET_NOMORE_DATA; @@ -579,7 +690,6 @@ begin STATE <= S_TEST_SELF_TRIGGER; end case; - if (STATE /= S_IDLE) then busy_time_ctr <= busy_time_ctr + 1; @@ -642,13 +752,14 @@ begin channel_done_r <= channel_done; channel_hit_r <= channel_hit; channel_wait_r <= channel_wait; + + when CS_CLEAR_WAIT => + channel_wait <= (others => '0'); when CS_TOKEN_UPDATE => - if (min_val_time_expired = '1') then - channel_done <= channel_done or (not channel_wait); - token_update <= '1'; - end if; - channel_wait <= (others => '0'); + channel_done <= channel_done or (not channel_wait); + token_update <= '1'; + channel_wait <= (others => '0'); when CS_SET_WAIT => channel_wait(to_integer(unsigned(channel_index))) <= '1'; @@ -709,6 +820,8 @@ begin readout_time_max <= x"3e8"; fpga_timestamp_offset <= (others => '0'); out_of_window_error_ctr_clear <= '0'; + skip_wait_for_data <= '0'; + nxyter_cv_time <= x"190"; -- 400ns else slv_data_out_o <= (others => '0'); slv_unknown_addr_o <= '0'; @@ -860,9 +973,45 @@ begin when x"0019" => slv_data_out_o(19 downto 0) <= wait_for_data_time_r; - slv_data_out_o(31 downto 20) <= (others => '0'); + slv_data_out_o(30 downto 20) <= (others => '0'); + slv_data_out_o(31) <= skip_wait_for_data; slv_ack_o <= '1'; - + + when x"001a" => + slv_data_out_o(11 downto 0) <= + std_logic_vector(nxyter_cv_time); + slv_data_out_o(31 downto 12) <= (others => '0'); + slv_ack_o <= '1'; + + when x"001b" => + slv_data_out_o(19 downto 0) <= + std_logic_vector(min_validation_time_r); + slv_data_out_o(31 downto 20) <= (others => '0'); + slv_ack_o <= '1'; + + when x"001c" => + slv_data_out_o(15 downto 0) <= + std_logic_vector(out_of_window_l_ctr_r); + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when x"001d" => + slv_data_out_o(15 downto 0) <= + std_logic_vector(window_hit_ctr_r); + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when x"001e" => + slv_data_out_o(15 downto 0) <= + std_logic_vector(out_of_window_h_ctr_r); + slv_data_out_o(31 downto 16) <= (others => '0'); + slv_ack_o <= '1'; + + when x"001f" => + slv_data_out_o(27 downto 0) <= std_logic_vector(data_rate); + slv_data_out_o(31 downto 28) <= (others => '0'); + slv_ack_o <= '1'; + when others => slv_unknown_addr_o <= '1'; slv_ack_o <= '0'; @@ -909,6 +1058,15 @@ begin out_of_window_error_ctr_clear <= '1'; slv_ack_o <= '1'; + when x"0019" => + skip_wait_for_data <= SLV_DATA_IN(31); + slv_ack_o <= '1'; + + when x"001a" => + nxyter_cv_time <= + unsigned(SLV_DATA_IN(11 downto 0)); + slv_ack_o <= '1'; + when others => slv_unknown_addr_o <= '1'; slv_ack_o <= '0'; diff --git a/nxyter/source/registers.txt b/nxyter/source/registers.txt index 30f4534..fc2bafe 100644 --- a/nxyter/source/registers.txt +++ b/nxyter/source/registers.txt @@ -13,9 +13,10 @@ 0x8107 : r ADC Data Clock Lock (187.5 MHz) 0x8108 : r ADC Sample Clock Lock (31.25 MHz) 0x8109 : r/w r: PLL Nxyter Main Clock NotLock Counter (16 Bit) - w: Clear all pll_nx_clk_notlock_ctr 0x810a : r PLL ADC Data Clock NotLock Counter (16 Bit) + w: Clear all NotLOck Counters 0x810b : r PLL ADC Sample Clock NotLock Counter (16 Bit) +0x810c : r All ERROR Flags (8 Bit) -- NX I2C Setup Handler 0x8200 : r/w I2C Memeory Register (Depth: 0 - 45 ... 0x822c) @@ -138,6 +139,8 @@ 0x8416 : r DONE flags ch 96..127 0x8417 : r channel_all_done 0x8418 : r EVT_BUFFER_FULL_IN +0x8419 : r Wait for Data time (ns) +0x841a : r Nxyter CVT (ns) -- Event Data Buffer 0x8600 : r read FIFO buffer @@ -151,6 +154,10 @@ 0x8040 : r/w Access to I2C Interface Chip Ids: 0x08 : nXyter 0x29 : AD7991-1 + Reg: 0x10 ADC Channel 0 slow nx channel + Reg: 0x20 ADC Channel 1 fast nx channel + Reg: 0x40 ADC Channel 2 Temperature + Reg: 0x80 ADC Channel 3 Current 0x50 : EEPROM 0x8041 : r Full I2C Word @@ -178,7 +185,7 @@ 10: nx_trigger_validate 11: nx_event_buffer 12: nx_histograms - + 13: Checkerboard --- Trigger Selction Window Setup -- 2.43.0