From 04765a5e94798a8af36f639e8776acb570f7690b Mon Sep 17 00:00:00 2001 From: Ludwig Maier Date: Tue, 28 Jan 2014 13:17:06 +0100 Subject: [PATCH] ADC I2C readout implemented --- nxyter/source/nx_i2c_master.vhd | 2 +- nxyter/source/nx_setup.vhd | 198 ++++++++++++++++++++++---- nxyter/source/nx_trigger_validate.vhd | 58 +++++--- nxyter/source/registers.txt | 20 ++- 4 files changed, 227 insertions(+), 51 deletions(-) diff --git a/nxyter/source/nx_i2c_master.vhd b/nxyter/source/nx_i2c_master.vhd index 30ce9f5..777a700 100644 --- a/nxyter/source/nx_i2c_master.vhd +++ b/nxyter/source/nx_i2c_master.vhd @@ -449,7 +449,7 @@ begin -- D[29:27] RESERVED set all to '0' -- D[26:24] I2C_NUM_BYTES number of bytes to be read 1..4 -- D[23:16] I2C_ADDRESS address of I2C chip - -- D[15:8] I2C_CMD command byte for access + -- D[15:8] I2C_REG_ADDRESS command byte for access -- D[7:0] I2C_DATA data to be written -- -- Read bit definition diff --git a/nxyter/source/nx_setup.vhd b/nxyter/source/nx_setup.vhd index 269ec21..c4f3978 100644 --- a/nxyter/source/nx_setup.vhd +++ b/nxyter/source/nx_setup.vhd @@ -46,6 +46,7 @@ architecture Behavioral of nx_setup is signal i2c_lock_1 : std_logic; signal i2c_lock_2 : std_logic; signal i2c_lock_3 : std_logic; + signal i2c_lock_4 : std_logic; signal i2c_command : std_logic_vector(31 downto 0); -- Send I2C Command @@ -85,8 +86,8 @@ architecture Behavioral of nx_setup is signal ram_write_1 : std_logic; signal do_write : std_logic; - -- DAC Trim FIFO RAM - type dac_ram_t is array(0 to 130) of std_logic_vector(5 downto 0); + -- DAC Trim FIFO RAM Handler + type dac_ram_t is array(0 to 128) of std_logic_vector(5 downto 0); signal dac_ram : dac_ram_t; signal dac_ram_write_0 : std_logic; signal dac_ram_write_1 : std_logic; @@ -95,7 +96,11 @@ architecture Behavioral of nx_setup is signal dac_ram_data_0 : std_logic_vector(5 downto 0); signal dac_ram_data_1 : std_logic_vector(5 downto 0); signal do_dac_write : std_logic; - + + -- ADC RAM Handler + type adc_ram_t is array(0 to 3) of std_logic_vector(15 downto 0); + signal adc_ram : adc_ram_t; + -- Token Handler signal i2c_read_token : std_logic_vector(45 downto 0); signal i2c_write_token : std_logic_vector(45 downto 0); @@ -133,7 +138,6 @@ architecture Behavioral of nx_setup is ); signal DR_STATE, DR_STATE_RETURN : DR_STATES; - signal dac_read_i2c_command : std_logic_vector(31 downto 0); signal r_fifo_ctr : unsigned(7 downto 0); @@ -155,6 +159,25 @@ architecture Behavioral of nx_setup is signal dac_write_token_clear : std_logic_vector(128 downto 0); signal next_token_dac_w : std_logic; signal i2c_lock_2_clear : std_logic; + + -- ADC Token Handler + signal adc_read_token : std_logic_vector(3 downto 0); + + -- Read ADC Registers + type ADC_STATES is (ADC_IDLE_TOKEN, + ADC_READ_I2C_REGISTER, + ADC_WAIT_I2C_READ_DONE, + ADC_READ_I2C_STORE_MEM, + ADC_NEXT_TOKEN + ); + + signal ADC_STATE : ADC_STATES; + + signal adc_i2c_command : std_logic_vector(31 downto 0); + signal adc_token_ctr : unsigned(1 downto 0); + signal adc_read_token_clear : std_logic_vector(3 downto 0); + signal next_token_adc : std_logic; + signal i2c_lock_4_clear : std_logic; -- I2C Online Check type R_STATES is (R_TIMER_RESTART, @@ -191,6 +214,8 @@ architecture Behavioral of nx_setup is signal dac_read_token_r : std_logic_vector(128 downto 0); signal dac_write_token_r : std_logic_vector(128 downto 0); + signal adc_read_token_r : std_logic_vector(3 downto 0); + signal nxyter_polarity : std_logic_vector(1 downto 0); -- 0: negative signal nxyter_testpulse : std_logic_vector(1 downto 0); signal nxyter_testtrigger : std_logic_vector(1 downto 0); @@ -214,12 +239,12 @@ begin DEBUG_OUT(7) <= i2c_lock_0_clear; DEBUG_OUT(8) <= i2c_lock_1_clear; DEBUG_OUT(9) <= i2c_lock_2_clear; - DEBUG_OUT(10) <= i2c_lock_3_clear; + DEBUG_OUT(10) <= i2c_lock_4_clear; DEBUG_OUT(11) <= i2c_online_o; DEBUG_OUT(12) <= i2c_lock_0; DEBUG_OUT(13) <= i2c_lock_1; DEBUG_OUT(14) <= i2c_lock_2; - DEBUG_OUT(15) <= i2c_lock_3; + DEBUG_OUT(15) <= i2c_lock_4; ----------------------------------------------------------------------------- @@ -291,11 +316,11 @@ begin end if; end if; end process PROC_DAC_RAM; - + ----------------------------------------------------------------------------- PROC_I2C_COMMAND_MULTIPLEXER: process(CLK_IN) - variable locks : std_logic_vector(3 downto 0) := (others => '0'); + variable locks : std_logic_vector(4 downto 0) := (others => '0'); begin if( rising_edge(CLK_IN) ) then if( RESET_IN = '1' ) then @@ -303,10 +328,13 @@ begin i2c_lock_1 <= '0'; i2c_lock_2 <= '0'; i2c_lock_3 <= '0'; + i2c_lock_4 <= '0'; i2c_command <= (others => '0'); else i2c_command <= (others => '0'); - locks := i2c_lock_3 & i2c_lock_2 & i2c_lock_1 & i2c_lock_0; + locks := i2c_lock_4 & i2c_lock_3 & + i2c_lock_2 & i2c_lock_1 & + i2c_lock_0; -- Clear Locks if (i2c_lock_0_clear = '1') then @@ -321,28 +349,36 @@ begin if (i2c_lock_3_clear = '1') then i2c_lock_3 <= '0'; end if; + if (i2c_lock_4_clear = '1') then + i2c_lock_4 <= '0'; + end if; if (i2c_command_busy_o = '0') then - if (nx_i2c_command(31) = '1' and - ((locks and "1110") = "0000") and - i2c_lock_0_clear = '0') then + if (nx_i2c_command(31) = '1' and + ((locks and "11110") = "00000") and + i2c_lock_0_clear = '0') then i2c_command <= nx_i2c_command; i2c_lock_0 <= '1'; - elsif (dac_write_i2c_command(31) = '1' and - ((locks and "1011") = "0000") and + elsif (dac_write_i2c_command(31) = '1' and + ((locks and "11011") = "00000") and i2c_lock_2_clear = '0') then i2c_command <= dac_write_i2c_command; i2c_lock_2 <= '1'; elsif (dac_read_i2c_command(31) = '1' and - ((locks and "1101") = "0000") and + ((locks and "11101") = "00000") and i2c_lock_1_clear = '0') then i2c_command <= dac_read_i2c_command; i2c_lock_1 <= '1'; - elsif (i2c_online_command(31) = '1' and - ((locks and "0111") = "0000") and + elsif (i2c_online_command(31) = '1' and + ((locks and "10111") = "00000") and i2c_lock_3_clear = '0') then i2c_command <= i2c_online_command; i2c_lock_3 <= '1'; + elsif (adc_i2c_command(31) = '1' and + ((locks and "01111") = "00000") and + i2c_lock_4_clear = '0') then + i2c_command <= adc_i2c_command; + i2c_lock_4 <= '1'; end if; end if; end if; @@ -466,6 +502,25 @@ begin end if; end process PROC_DAC_TOKEN_HANDLER; + + PROC_ADC_TOKEN_HANDLER: process(CLK_IN) + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + adc_read_token <= (others => '0'); + else + -- Read Token + if (i2c_update_memory = '1') then + adc_read_token <= (others => '1'); + elsif (unsigned(adc_read_token_r) /= 0) then + adc_read_token <= (adc_read_token or adc_read_token_r); + elsif (unsigned(adc_read_token_clear) /= 0) then + adc_read_token <= adc_read_token and (not adc_read_token_clear); + end if; + end if; + end if; + end process PROC_ADC_TOKEN_HANDLER; + ----------------------------------------------------------------------------- PROC_I2C_REGISTERS_HANDLER: process(CLK_IN) @@ -683,10 +738,10 @@ begin w_fifo_ctr <= (others => '0'); when DW_REGISTER => - dac_write_i2c_command(31 downto 16) <= x"c108"; - dac_write_i2c_command(15 downto 8) <= x"2a"; -- DAC Reg 42 - dac_write_i2c_command(7 downto 0) <= (others => '0'); - dac_write_token_clear(index) <= '1'; + dac_write_i2c_command(31 downto 16) <= x"c108"; + dac_write_i2c_command(15 downto 8) <= x"2a"; -- DAC Reg 42 + dac_write_i2c_command(7 downto 0) <= (others => '0'); + dac_write_token_clear(index) <= '1'; if (i2c_lock_2 = '0') then DW_STATE <= DW_REGISTER; else @@ -706,7 +761,7 @@ begin when DW_NEXT_REGISTER => if (w_fifo_ctr < x"80") then - w_fifo_ctr <= w_fifo_ctr + 1; + w_fifo_ctr <= w_fifo_ctr + 1; next_token_dac_w <= '1'; DW_STATE <= DW_REGISTER; else @@ -727,7 +782,82 @@ begin end process PROC_WRITE_DAC_REGISTERS; ----------------------------------------------------------------------------- + + PROC_ADC_REGISTERS_HANDLER: process(CLK_IN) + variable index : integer := 0; + begin + if( rising_edge(CLK_IN) ) then + if( RESET_IN = '1' ) then + adc_i2c_command <= (others => '0'); + adc_token_ctr <= (others => '0'); + next_token_adc <= '0'; + adc_read_token_clear <= (others => '0'); + i2c_lock_4_clear <= '0'; + ADC_STATE <= ADC_IDLE_TOKEN; + else + index := to_integer(unsigned(adc_token_ctr)); + adc_i2c_command <= (others => '0'); + next_token_adc <= '0'; + adc_read_token_clear <= (others => '0'); + i2c_lock_4_clear <= '0'; + + case ADC_STATE is + + when ADC_IDLE_TOKEN => + if (adc_read_token(index) = '1') then + ADC_STATE <= ADC_READ_I2C_REGISTER; + else + ADC_STATE <= ADC_NEXT_TOKEN; + end if; + + -- Read I2C Register + when ADC_READ_I2C_REGISTER => + adc_i2c_command(31 downto 16) <= x"c229"; + adc_i2c_command(15 downto 14) <= (others => '0'); + case adc_token_ctr is + when "00" => adc_i2c_command(15 downto 12) <= "0000"; + when "01" => adc_i2c_command(15 downto 12) <= "0001"; + when "10" => adc_i2c_command(15 downto 12) <= "0010"; + when "11" => adc_i2c_command(15 downto 12) <= "0100"; + end case; + adc_i2c_command(11 downto 8) <= "0000"; + adc_i2c_command( 7 downto 0) <= (others => '0'); + if (i2c_lock_4 = '0') then + ADC_STATE <= ADC_READ_I2C_REGISTER; + else + adc_read_token_clear(index) <= '1'; + ADC_STATE <= ADC_WAIT_I2C_READ_DONE; + end if; + + when ADC_WAIT_I2C_READ_DONE => + if (i2c_command_done = '0') then + ADC_STATE <= ADC_WAIT_I2C_READ_DONE; + else + ADC_STATE <= ADC_READ_I2C_STORE_MEM; + end if; + + when ADC_READ_I2C_STORE_MEM => + adc_ram(index) <= i2c_data(15 downto 0); + i2c_lock_4_clear <= '1'; + ADC_STATE <= ADC_NEXT_TOKEN; + + -- Next Token + when ADC_NEXT_TOKEN => + if (adc_token_ctr < "11") then + adc_token_ctr <= adc_token_ctr + 1; + else + adc_token_ctr <= (others => '0'); + end if; + next_token_adc <= '1'; + ADC_STATE <= ADC_IDLE_TOKEN; + + end case; + end if; + end if; + end process PROC_ADC_REGISTERS_HANDLER; + ----------------------------------------------------------------------------- + nx_timer_1: nx_timer generic map ( CTR_WIDTH => 32 @@ -889,6 +1019,7 @@ begin dac_ram_index_0 <= 0; dac_ram_write_0 <= '0'; dac_read_token_r <= (others => '0'); + adc_read_token_r <= (others => '0'); i2c_update_memory_r <= '0'; nxyter_clock <= (others => '0'); nxyter_polarity <= (others => '0'); @@ -909,6 +1040,9 @@ begin dac_ram_index_0 <= 0; dac_ram_write_0 <= '0'; dac_read_token_r <= (others => '0'); + + adc_read_token_r <= (others => '0'); + i2c_update_memory_r <= '0'; nxyter_clock <= (others => '0'); nxyter_polarity <= (others => '0'); @@ -917,7 +1051,7 @@ begin nxyter_testchannels <= (others => '0'); if (SLV_WRITE_IN = '1') then - if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN < x"002e") then + if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then index := to_integer(unsigned(SLV_ADDR_IN(5 downto 0))); if (i2c_disable_memory = '0') then ram_index_0 <= index; @@ -926,7 +1060,7 @@ begin end if; slv_ack_o <= '1'; - elsif (SLV_ADDR_IN >= x"0100" and SLV_ADDR_IN < x"0181") then + elsif (SLV_ADDR_IN >= x"0100" and SLV_ADDR_IN <= x"0180") then -- Write value to ram index := to_integer(unsigned(SLV_ADDR_IN(7 downto 0))); if (i2c_disable_memory = '0') then @@ -1004,7 +1138,7 @@ begin end if; elsif (SLV_READ_IN = '1') then - if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN < x"002e") then + if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then index := to_integer(unsigned(SLV_ADDR_IN(5 downto 0))); if (i2c_disable_memory = '0') then slv_data_out_o(7 downto 0) <= i2c_ram(index); @@ -1022,7 +1156,7 @@ begin index := to_integer(unsigned(SLV_ADDR_IN(7 downto 0))); if (i2c_disable_memory = '0') then slv_data_out_o(5 downto 0) <= dac_ram(index); - slv_data_out_o(31 downto 6) <= (others => '0'); + slv_data_out_o(29 downto 6) <= (others => '0'); slv_data_out_o(30) <= dac_read_token(index); slv_data_out_o(31) <= dac_write_token(index); else @@ -1030,6 +1164,18 @@ begin end if; slv_ack_o <= '1'; + elsif (SLV_ADDR_IN >= x"0080" and SLV_ADDR_IN <= x"0083") then + index := to_integer(unsigned(SLV_ADDR_IN(1 downto 0))); + if (i2c_disable_memory = '0') then + slv_data_out_o(15 downto 0) <= adc_ram(index); + slv_data_out_o(30 downto 16) <= (others => '0'); + slv_data_out_o(31) <= adc_read_token(index); + adc_read_token_r(index) <= '1'; + else + slv_data_out_o(31 downto 0) <= (others => '1'); + end if; + slv_ack_o <= '1'; + else case SLV_ADDR_IN is when x"0050" => diff --git a/nxyter/source/nx_trigger_validate.vhd b/nxyter/source/nx_trigger_validate.vhd index 50cfbb4..da864ba 100644 --- a/nxyter/source/nx_trigger_validate.vhd +++ b/nxyter/source/nx_trigger_validate.vhd @@ -352,36 +352,56 @@ begin end if; if (store_data = '1') then + case readout_mode(1 downto 0) is when "00" => - -- RefValue + TS window filter + ovfl valid + parity valid + -- RefValue + TS window filter + parity valid + if (TIMESTAMP_STATUS_IN(2) = '0') then + d_data_o(10 downto 0) <= deltaTStore(10 downto 0); + d_data_o(22 downto 11) <= ADC_DATA_IN; + d_data_o(29 downto 23) <= CHANNEL_IN; + d_data_o(31 downto 30) <= + TIMESTAMP_STATUS_IN(1 downto 0); + d_data_clk_o <= '1'; + end if; + + when "01" => + -- RefValue + TS window filter + pileup and Overflow valid + -- parity valid if (TIMESTAMP_STATUS_IN(2) = '0' and TIMESTAMP_STATUS_IN(0) = '0') then - d_data_o(11 downto 0) <= deltaTStore(11 downto 0); - d_data_o(23 downto 12) <= ADC_DATA_IN; - d_data_o(30 downto 24) <= CHANNEL_IN; - d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + d_data_o(10 downto 0) <= deltaTStore(10 downto 0); + d_data_o(22 downto 11) <= ADC_DATA_IN; + d_data_o(29 downto 23) <= CHANNEL_IN; + d_data_o(31 downto 30) <= + TIMESTAMP_STATUS_IN(1 downto 0); d_data_clk_o <= '1'; end if; - when "01" => - -- RefValue + TS window filter + ovfl and pileup valid - -- + parity valid - if (TIMESTAMP_STATUS_IN = "000") then - d_data_o(11 downto 0) <= deltaTStore(11 downto 0); - d_data_o(23 downto 12) <= ADC_DATA_IN; - d_data_o(30 downto 24) <= CHANNEL_IN; - d_data_o(31) <= TIMESTAMP_STATUS_IN(1); + when "10" => + -- RefValue + TS window filter + pileup, Overflow and pileup + -- valid + -- parity valid + if (TIMESTAMP_STATUS_IN(2) = '0' and + TIMESTAMP_STATUS_IN(1) = '0' and + TIMESTAMP_STATUS_IN(0) = '0') then + d_data_o(10 downto 0) <= deltaTStore(10 downto 0); + d_data_o(22 downto 11) <= ADC_DATA_IN; + d_data_o(29 downto 23) <= CHANNEL_IN; + d_data_o(31 downto 30) <= + TIMESTAMP_STATUS_IN(1 downto 0); d_data_clk_o <= '1'; end if; - + when others => + d_data_o(10 downto 0) <= deltaTStore(10 downto 0); + d_data_o(22 downto 11) <= ADC_DATA_IN; + d_data_o(29 downto 23) <= CHANNEL_IN; + d_data_o(31 downto 30) <= + TIMESTAMP_STATUS_IN(1 downto 0); + d_data_clk_o <= '1'; -- RefValue + ignore status - d_data_o(11 downto 0) <= deltaTStore(11 downto 0); - d_data_o(23 downto 12) <= ADC_DATA_IN; - d_data_o(30 downto 24) <= CHANNEL_IN; - d_data_o(31) <= TIMESTAMP_STATUS_IN(1); - d_data_clk_o <= '1'; + end case; end if; diff --git a/nxyter/source/registers.txt b/nxyter/source/registers.txt index 07d260c..b72180a 100644 --- a/nxyter/source/registers.txt +++ b/nxyter/source/registers.txt @@ -19,7 +19,8 @@ 0x810c : r All ERROR Flags (8 Bit) -- NX I2C Setup Handler -0x8200 : r/w I2C Memeory Register (Depth: 0 - 45 ... 0x822c) +0x8200 : r/w I2C Memory Register (Depth: 0 - 45 ... 0x822c) +0x8280 : r ADC Memory Register (Depth: 0 - 3 ... 0x8283) 0x8300 : r/w DAC Register Memory (Depth: 0 - 128 ... 0x82e0) 0x8250 : r/w Enable Nxyter Clock 0x8251 : r/w Nxyter Polarity @@ -170,10 +171,19 @@ 0x8060 : Access to SPI Interface -- Histogram Handler -0x8800 : r/w r: Read Channel Statistic (128 channel in a row) - w: reset all Histograms -0x8880 : r Read Channel Trigger Rate (128 channel in a row, 1/s) -0x8900 : r Read Channel ADC Value (128 channel in a row) +0x8800 : r/w r: Read Channel HIt Statistic (128 channel in a row) +0x8900 : r Read Channel Trigger Rate (128 channel in a row, 1/s) +0x8a00 : r Read Channel averaged ADC Value (128 channel in a row) +0x8b00 : r Read Channel PileUp Rate (128 channel in a row, 1/s) + +0x8880 : r/w Hit Rate num averages (3 Bit) +0x8881 : r/w Hit Rate average enable +0x8980 : r/w ADC num averages (3 Bit) +0x8981 : r/w ADC average enable +0x8a80 : r/w PileUp Rate num averages (3 Bit) +0x8a81 : r/w PileUp Rate average enable +0x8b80 : r/w Overflow Rate num averages (3 Bit) +0x8b81 : r/w Overflow Rate average enable -- Debug Multiplexer 0x8020 : r/w Select Debug Entity -- 2.43.0