use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-library work;
use work.trb_net_std.all;
use work.trb3_components.all;
use work.adc_package.all;
+use work.config.all;
entity adc_handler is
port(
signal adc_valid_out : std_logic_vector(DEVICES - 1 downto 0);
signal adc_debug : std_logic_vector(DEVICES * 32 - 1 downto 0);
- signal buffer_empty : std_logic;
- signal buffer_stop_override : std_logic;
-
signal ctrl_reg : std_logic_vector(31 downto 0);
signal strobe_reg : std_logic_vector(31 downto 0);
attribute syn_keep of ctrl_reg : signal is true;
signal adc_stop : std_logic;
signal config : cfg_t;
+ signal config_cfd : cfg_t;
signal buffer_addr : std_logic_vector(4 downto 0);
signal buffer_data : buffer_data_t;
signal buffer_read : std_logic_vector(15 downto 0);
DEBUG(32 * 5 - 1 downto 32 * 1) => adc_debug(32 * 12 - 1 downto 32 * 8)
);
- gen_processors : for i in 0 to DEVICES - 1 generate
- THE_ADC_PROC : entity work.adc_processor
- generic map(
- DEVICE => i
- )
- port map(
- CLK => CLK,
- ADC_DATA => adc_data_out((i + 1) * RESOLUTION * CHANNELS - 1 downto i * RESOLUTION * CHANNELS),
- ADC_VALID => adc_valid_out(i),
- STOP_IN => adc_stop,
- TRIGGER_OUT => adc_trigger(i),
- CONTROL(31 downto 0) => strobe_reg,
- CONTROL(63 downto 32) => buffer_ctrl_reg,
- CONFIG => config, --trigger offset, zero sup offset, depth,
-
- PSA_DATA => psa_data,
- PSA_DATA_OUT => psa_data_out(i),
- PSA_ADDR => psa_addr,
- PSA_WRITE => psa_write,
- DEBUG_BUFFER_ADDR => buffer_addr,
- DEBUG_BUFFER_READ => buffer_read(i),
- DEBUG_BUFFER_DATA => buffer_data(i),
- DEBUG_BUFFER_READY => buffer_ready(i),
- READOUT_RX => READOUT_RX,
- READOUT_TX => READOUT_TX(i)
- );
- end generate;
+ --------------------------------------------
+ -- For both readout modes
+ --------------------------------------------
TRIGGER_FLAG_OUT <= or_all(adc_trigger);
ADCSPI_CTRL <= ctrl_reg(7 downto 0);
- adc_stop <= buffer_ctrl_reg(0);
- config.baseline_always_on <= buffer_ctrl_reg(4);
+ --------------------------------------------
+ -- PSA readout mode
+ --------------------------------------------
+ gen_readout_psa : if READOUT_MODE = READOUT_MODE_PSA generate
+ gen_processors : for i in 0 to DEVICES - 1 generate
+ THE_ADC_PROC : entity work.adc_processor
+ generic map(
+ DEVICE => i
+ )
+ port map(
+ CLK => CLK,
+ ADC_DATA => adc_data_out((i + 1) * RESOLUTION * CHANNELS - 1 downto i * RESOLUTION * CHANNELS),
+ ADC_VALID => adc_valid_out(i),
+ STOP_IN => adc_stop,
+ TRIGGER_OUT => adc_trigger(i),
+ CONTROL(31 downto 0) => strobe_reg,
+ CONTROL(63 downto 32) => buffer_ctrl_reg,
+ CONFIG => config, --trigger offset, zero sup offset, depth,
- PROC_BUS : process
- begin
- wait until rising_edge(CLK);
- BUS_TX.ack <= '0';
- BUS_TX.nack <= '0';
- BUS_TX.unknown <= '0';
- buffer_read <= (others => '0');
- strobe_reg <= (others => '0');
- psa_write <= '0';
- if or_all(buffer_ready) = '1' then
- BUS_TX.data <= buffer_data(buffer_device);
- BUS_TX.ack <= '1';
- elsif BUS_RX.read = '1' then
- if BUS_RX.addr <= x"000f" then
- BUS_TX.ack <= '1';
- case BUS_RX.addr(3 downto 0) is
- when x"1" => BUS_TX.data <= buffer_ctrl_reg;
- when others => BUS_TX.ack <= '0';
- BUS_TX.unknown <= '1';
- end case;
- elsif BUS_RX.addr = x"0080" then
- BUS_TX.data <= ctrl_reg;
- BUS_TX.ack <= '1';
- elsif BUS_RX.addr >= x"0010" and BUS_RX.addr <= x"001f" then --basic config registers
- BUS_TX.ack <= '1';
- BUS_TX.data <= (others => '0');
- case BUS_RX.addr(7 downto 0) is
- when x"10" => BUS_TX.data(10 downto 0) <= std_logic_vector(config.buffer_depth);
- when x"11" => BUS_TX.data(10 downto 0) <= std_logic_vector(config.samples_after);
- when x"12" => BUS_TX.data(1 downto 0) <= std_logic_vector(config.block_count);
- when x"13" => BUS_TX.data(17 downto 0) <= std_logic_vector(config.trigger_threshold);
- when x"14" => BUS_TX.data(17 downto 0) <= std_logic_vector(config.readout_threshold);
- when x"15" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.presum);
- when x"16" => BUS_TX.data(3 downto 0) <= std_logic_vector(config.averaging);
- when x"17" => BUS_TX.data(31 downto 0) <= config.trigger_enable(31 downto 0);
- when x"18" => BUS_TX.data(15 downto 0) <= config.trigger_enable(47 downto 32);
- when x"19" => BUS_TX.data(RESOLUTION - 1 downto 0) <= config.check_word1;
- BUS_TX.data(RESOLUTION - 1 + 16 downto 16) <= config.check_word2;
- BUS_TX.data(31) <= config.check_word_enable;
- when x"1a" => BUS_TX.data(31 downto 0) <= config.channel_disable(31 downto 0);
- when x"1b" => BUS_TX.data(15 downto 0) <= config.channel_disable(47 downto 32);
- when x"1c" => BUS_TX.data(1 downto 0) <= std_logic_vector(to_unsigned(config.processing_mode, 2));
- when x"1d" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.cfd_window);
- BUS_TX.data(11 downto 8) <= std_logic_vector(config.cfd_delay);
- when others => BUS_TX.ack <= '0';
- BUS_TX.unknown <= '1';
- end case;
- elsif BUS_RX.addr >= x"0020" and BUS_RX.addr <= x"002f" then
- BUS_TX.ack <= '1';
- BUS_TX.data <= (others => '0');
- case BUS_RX.addr(3 downto 2) is
- when "00" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.block_avg(to_integer(unsigned(BUS_RX.addr(1 downto 0)))));
- when "01" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.block_sums(to_integer(unsigned(BUS_RX.addr(1 downto 0)))));
- when "10" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.block_scale(to_integer(unsigned(BUS_RX.addr(1 downto 0)))));
- when "11" => BUS_TX.ack <= '0';
- BUS_TX.unknown <= '1';
- end case;
- elsif BUS_RX.addr >= x"0030" and BUS_RX.addr <= x"003b" then
+ PSA_DATA => psa_data,
+ PSA_DATA_OUT => psa_data_out(i),
+ PSA_ADDR => psa_addr,
+ PSA_WRITE => psa_write,
+ DEBUG_BUFFER_ADDR => buffer_addr,
+ DEBUG_BUFFER_READ => buffer_read(i),
+ DEBUG_BUFFER_DATA => buffer_data(i),
+ DEBUG_BUFFER_READY => buffer_ready(i),
+ READOUT_RX => READOUT_RX,
+ READOUT_TX => READOUT_TX(i)
+ );
+ end generate;
+
+ adc_stop <= buffer_ctrl_reg(0);
+ config.baseline_always_on <= buffer_ctrl_reg(4);
+
+ PROC_BUS : process
+ begin
+ wait until rising_edge(CLK);
+ BUS_TX.ack <= '0';
+ BUS_TX.nack <= '0';
+ BUS_TX.unknown <= '0';
+ buffer_read <= (others => '0');
+ strobe_reg <= (others => '0');
+ psa_write <= '0';
+ if or_all(buffer_ready) = '1' then
+ BUS_TX.data <= buffer_data(buffer_device);
BUS_TX.ack <= '1';
- BUS_TX.data <= adc_debug(to_integer(unsigned(BUS_RX.addr(3 downto 0))) * 32 + 31 downto to_integer(unsigned(BUS_RX.addr(3 downto 0))) * 32);
- elsif BUS_RX.addr >= x"0800" and BUS_RX.addr <= x"08ff" and BUS_RX.addr(5 downto 0) < std_logic_vector(to_unsigned(DEVICES * CHANNELS, 6)) then
- buffer_device <= to_integer(unsigned(BUS_RX.addr(5 downto 2)));
- buffer_addr <= '0' & BUS_RX.addr(7 downto 6) & BUS_RX.addr(1 downto 0);
- buffer_read(to_integer(unsigned(BUS_RX.addr(5 downto 2)))) <= '1';
- elsif BUS_RX.addr >= x"0900" and BUS_RX.addr <= x"09ff" then
- if BUS_RX.addr(3 downto 0) < std_logic_vector(to_unsigned(DEVICES, 4)) then
- buffer_device <= to_integer(unsigned(BUS_RX.addr(3 downto 0)));
- buffer_addr <= '1' & BUS_RX.addr(7 downto 4);
- buffer_read(to_integer(unsigned(BUS_RX.addr(3 downto 0)))) <= '1';
- else
+ elsif BUS_RX.read = '1' then
+ if BUS_RX.addr <= x"000f" then
+ BUS_TX.ack <= '1';
+ case BUS_RX.addr(3 downto 0) is
+ when x"1" => BUS_TX.data <= buffer_ctrl_reg;
+ when others => BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
+ end case;
+ elsif BUS_RX.addr = x"0080" then
+ BUS_TX.data <= ctrl_reg;
+ BUS_TX.ack <= '1';
+ elsif BUS_RX.addr >= x"0010" and BUS_RX.addr <= x"001f" then --basic config registers
+ BUS_TX.ack <= '1';
+ BUS_TX.data <= (others => '0');
+ case BUS_RX.addr(7 downto 0) is
+ when x"10" => BUS_TX.data(10 downto 0) <= std_logic_vector(config.buffer_depth);
+ when x"11" => BUS_TX.data(10 downto 0) <= std_logic_vector(config.samples_after);
+ when x"12" => BUS_TX.data(1 downto 0) <= std_logic_vector(config.block_count);
+ when x"13" => BUS_TX.data(17 downto 0) <= std_logic_vector(config.trigger_threshold);
+ when x"14" => BUS_TX.data(17 downto 0) <= std_logic_vector(config.readout_threshold);
+ when x"15" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.presum);
+ when x"16" => BUS_TX.data(3 downto 0) <= std_logic_vector(config.averaging);
+ when x"17" => BUS_TX.data(31 downto 0) <= config.trigger_enable(31 downto 0);
+ when x"18" => BUS_TX.data(15 downto 0) <= config.trigger_enable(47 downto 32);
+ when x"19" => BUS_TX.data(RESOLUTION - 1 downto 0) <= config.check_word1;
+ BUS_TX.data(RESOLUTION - 1 + 16 downto 16) <= config.check_word2;
+ BUS_TX.data(31) <= config.check_word_enable;
+ when x"1a" => BUS_TX.data(31 downto 0) <= config.channel_disable(31 downto 0);
+ when x"1b" => BUS_TX.data(15 downto 0) <= config.channel_disable(47 downto 32);
+ when x"1c" => BUS_TX.data(1 downto 0) <= std_logic_vector(to_unsigned(config.processing_mode, 2));
+ when x"1d" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.cfd_window);
+ BUS_TX.data(11 downto 8) <= std_logic_vector(config.cfd_delay);
+ when others => BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
+ end case;
+ elsif BUS_RX.addr >= x"0020" and BUS_RX.addr <= x"002f" then
+ BUS_TX.ack <= '1';
BUS_TX.data <= (others => '0');
+ case BUS_RX.addr(3 downto 2) is
+ when "00" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.block_avg(to_integer(unsigned(BUS_RX.addr(1 downto 0)))));
+ when "01" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.block_sums(to_integer(unsigned(BUS_RX.addr(1 downto 0)))));
+ when "10" => BUS_TX.data(7 downto 0) <= std_logic_vector(config.block_scale(to_integer(unsigned(BUS_RX.addr(1 downto 0)))));
+ when "11" => BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
+ end case;
+ elsif BUS_RX.addr >= x"0030" and BUS_RX.addr <= x"003b" then
BUS_TX.ack <= '1';
+ BUS_TX.data <= adc_debug(to_integer(unsigned(BUS_RX.addr(3 downto 0))) * 32 + 31 downto to_integer(unsigned(BUS_RX.addr(3 downto 0))) * 32);
+ elsif BUS_RX.addr >= x"0800" and BUS_RX.addr <= x"08ff" and BUS_RX.addr(5 downto 0) < std_logic_vector(to_unsigned(DEVICES * CHANNELS, 6)) then
+ buffer_device <= to_integer(unsigned(BUS_RX.addr(5 downto 2)));
+ buffer_addr <= '0' & BUS_RX.addr(7 downto 6) & BUS_RX.addr(1 downto 0);
+ buffer_read(to_integer(unsigned(BUS_RX.addr(5 downto 2)))) <= '1';
+ elsif BUS_RX.addr >= x"0900" and BUS_RX.addr <= x"09ff" then
+ if BUS_RX.addr(3 downto 0) < std_logic_vector(to_unsigned(DEVICES, 4)) then
+ buffer_device <= to_integer(unsigned(BUS_RX.addr(3 downto 0)));
+ buffer_addr <= '1' & BUS_RX.addr(7 downto 4);
+ buffer_read(to_integer(unsigned(BUS_RX.addr(3 downto 0)))) <= '1';
+ else
+ BUS_TX.data <= (others => '0');
+ BUS_TX.ack <= '1';
+ end if;
+ else
+ BUS_TX.unknown <= '1';
end if;
- else
- BUS_TX.unknown <= '1';
- end if;
- elsif BUS_RX.write = '1' then
- if BUS_RX.addr >= x"0010" and BUS_RX.addr <= x"001f" then --basic config registers
- BUS_TX.ack <= '1';
- case BUS_RX.addr(7 downto 0) is
- when x"10" => config.buffer_depth <= unsigned(BUS_RX.data(10 downto 0));
- when x"11" => config.samples_after <= unsigned(BUS_RX.data(10 downto 0));
- when x"12" => config.block_count <= unsigned(BUS_RX.data(1 downto 0));
- when x"13" => config.trigger_threshold <= unsigned(BUS_RX.data(17 downto 0));
- when x"14" => config.readout_threshold <= unsigned(BUS_RX.data(17 downto 0));
- when x"15" => config.presum <= unsigned(BUS_RX.data(7 downto 0));
- when x"16" => config.averaging <= unsigned(BUS_RX.data(3 downto 0));
- when x"17" => config.trigger_enable(31 downto 0) <= BUS_RX.data(31 downto 0);
- when x"18" => config.trigger_enable(47 downto 32) <= BUS_RX.data(15 downto 0);
- when x"19" => config.check_word1 <= BUS_RX.data(RESOLUTION - 1 downto 0);
- config.check_word2 <= BUS_RX.data(RESOLUTION - 1 + 16 downto 16);
- config.check_word_enable <= BUS_RX.data(31);
- when x"1a" => config.channel_disable(31 downto 0) <= BUS_RX.data(31 downto 0);
- when x"1b" => config.channel_disable(47 downto 32) <= BUS_RX.data(15 downto 0);
- when x"1c" => config.processing_mode <= to_integer(unsigned(BUS_RX.data(1 downto 0)));
- when x"1d" => config.cfd_window <= unsigned(BUS_RX.data(7 downto 0));
- config.cfd_delay <= unsigned(BUS_RX.data(11 downto 8));
- when others => BUS_TX.ack <= '0';
- BUS_TX.unknown <= '1';
- end case;
- elsif BUS_RX.addr >= x"0020" and BUS_RX.addr <= x"002f" then
- BUS_TX.ack <= '1';
- BUS_TX.data <= (others => '0');
- case BUS_RX.addr(3 downto 2) is
- when "00" => config.block_avg(to_integer(unsigned(BUS_RX.addr(1 downto 0)))) <= unsigned(BUS_RX.data(7 downto 0));
- when "01" => config.block_sums(to_integer(unsigned(BUS_RX.addr(1 downto 0)))) <= unsigned(BUS_RX.data(7 downto 0));
- when "10" => config.block_scale(to_integer(unsigned(BUS_RX.addr(1 downto 0)))) <= unsigned(BUS_RX.data(7 downto 0));
- when "11" => BUS_TX.ack <= '0';
- BUS_TX.unknown <= '1';
- end case;
- elsif BUS_RX.addr <= x"000f" then
- BUS_TX.ack <= '1';
- case BUS_RX.addr(3 downto 0) is
- when x"0" => strobe_reg <= BUS_RX.data;
- when x"1" => buffer_ctrl_reg <= BUS_RX.data;
- when others => BUS_TX.ack <= '0';
- BUS_TX.unknown <= '1';
- end case;
- elsif BUS_RX.addr = x"0080" then
- ctrl_reg <= BUS_RX.data;
- BUS_TX.ack <= '1';
- elsif BUS_RX.addr >= x"0200" and BUS_RX.addr <= x"02FF" then
- psa_data <= BUS_RX.data(8 downto 0);
- psa_write <= '1';
- psa_addr <= BUS_RX.addr(7 downto 0);
- BUS_TX.ack <= '1';
- else
- BUS_TX.unknown <= '1';
+ elsif BUS_RX.write = '1' then
+ if BUS_RX.addr >= x"0010" and BUS_RX.addr <= x"001f" then --basic config registers
+ BUS_TX.ack <= '1';
+ case BUS_RX.addr(7 downto 0) is
+ when x"10" => config.buffer_depth <= unsigned(BUS_RX.data(10 downto 0));
+ when x"11" => config.samples_after <= unsigned(BUS_RX.data(10 downto 0));
+ when x"12" => config.block_count <= unsigned(BUS_RX.data(1 downto 0));
+ when x"13" => config.trigger_threshold <= unsigned(BUS_RX.data(17 downto 0));
+ when x"14" => config.readout_threshold <= unsigned(BUS_RX.data(17 downto 0));
+ when x"15" => config.presum <= unsigned(BUS_RX.data(7 downto 0));
+ when x"16" => config.averaging <= unsigned(BUS_RX.data(3 downto 0));
+ when x"17" => config.trigger_enable(31 downto 0) <= BUS_RX.data(31 downto 0);
+ when x"18" => config.trigger_enable(47 downto 32) <= BUS_RX.data(15 downto 0);
+ when x"19" => config.check_word1 <= BUS_RX.data(RESOLUTION - 1 downto 0);
+ config.check_word2 <= BUS_RX.data(RESOLUTION - 1 + 16 downto 16);
+ config.check_word_enable <= BUS_RX.data(31);
+ when x"1a" => config.channel_disable(31 downto 0) <= BUS_RX.data(31 downto 0);
+ when x"1b" => config.channel_disable(47 downto 32) <= BUS_RX.data(15 downto 0);
+ when x"1c" => config.processing_mode <= to_integer(unsigned(BUS_RX.data(1 downto 0)));
+ when x"1d" => config.cfd_window <= unsigned(BUS_RX.data(7 downto 0));
+ config.cfd_delay <= unsigned(BUS_RX.data(11 downto 8));
+ when others => BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
+ end case;
+ elsif BUS_RX.addr >= x"0020" and BUS_RX.addr <= x"002f" then
+ BUS_TX.ack <= '1';
+ BUS_TX.data <= (others => '0');
+ case BUS_RX.addr(3 downto 2) is
+ when "00" => config.block_avg(to_integer(unsigned(BUS_RX.addr(1 downto 0)))) <= unsigned(BUS_RX.data(7 downto 0));
+ when "01" => config.block_sums(to_integer(unsigned(BUS_RX.addr(1 downto 0)))) <= unsigned(BUS_RX.data(7 downto 0));
+ when "10" => config.block_scale(to_integer(unsigned(BUS_RX.addr(1 downto 0)))) <= unsigned(BUS_RX.data(7 downto 0));
+ when "11" => BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
+ end case;
+ elsif BUS_RX.addr <= x"000f" then
+ BUS_TX.ack <= '1';
+ case BUS_RX.addr(3 downto 0) is
+ when x"0" => strobe_reg <= BUS_RX.data;
+ when x"1" => buffer_ctrl_reg <= BUS_RX.data;
+ when others => BUS_TX.ack <= '0';
+ BUS_TX.unknown <= '1';
+ end case;
+ elsif BUS_RX.addr = x"0080" then
+ ctrl_reg <= BUS_RX.data;
+ BUS_TX.ack <= '1';
+ elsif BUS_RX.addr >= x"0200" and BUS_RX.addr <= x"02FF" then
+ psa_data <= BUS_RX.data(8 downto 0);
+ psa_write <= '1';
+ psa_addr <= BUS_RX.addr(7 downto 0);
+ BUS_TX.ack <= '1';
+ else
+ BUS_TX.unknown <= '1';
+ end if;
end if;
- end if;
- end process;
+ end process;
+
+ proc_baseline_reset_value : process
+ begin
+ wait until rising_edge(CLK);
+ baseline_reset_value(3) <= (others => '0');
+ baseline_reset_value(3)(to_integer(config.averaging) + RESOLUTION - 1 downto to_integer(config.averaging)) <= (others => not config.trigger_threshold(16));
+ baseline_reset_value(2) <= baseline_reset_value(3);
+ baseline_reset_value(1) <= baseline_reset_value(2)(23 downto 0) * resize(config.presum + 1, 8);
+ baseline_reset_value(0) <= baseline_reset_value(1);
+ end process;
+ config.baseline_reset_value <= baseline_reset_value(0);
+
+ end generate;
+
+ --------------------------------------------
+ -- CFD readout mode
+ --------------------------------------------
- proc_baseline_reset_value : process
- begin
- wait until rising_edge(CLK);
- baseline_reset_value(3) <= (others => '0');
- baseline_reset_value(3)(to_integer(config.averaging) + RESOLUTION - 1 downto to_integer(config.averaging)) <= (others => not config.trigger_threshold(16));
- baseline_reset_value(2) <= baseline_reset_value(3);
- baseline_reset_value(1) <= baseline_reset_value(2)(23 downto 0) * resize(config.presum + 1, 8);
- baseline_reset_value(0) <= baseline_reset_value(1);
- end process;
- config.baseline_reset_value <= baseline_reset_value(0);
+ gen_readout_cfd : if READOUT_MODE = READOUT_MODE_CFD generate
+ end generate;
end architecture;