redpitaya-puzzlefw/fpga/rtl/acquisition_chain.vhd

189 lines
6.7 KiB
VHDL

--
-- Analog acquisition chain.
--
-- Joris van Rantwijk 2024
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.puzzlefw_pkg.all;
entity acquisition_chain is
generic (
-- Number of analog input channels. It should be either 2 or 4.
-- If num_channels == 2, the acquisition always runs in 2-channel mode.
-- IF num_channels == 4, the acquisition can run in 2-channel mode
-- or 4-channel mode.
num_channels: integer range 2 to 4
);
port (
-- Main clock, active on rising edge.
clk: in std_logic;
-- Reset, active high, synchronous to main clock.
reset: in std_logic;
-- High to enable data acquisition.
-- Low to disable data acquisition, ignore triggers, stop emitting
-- samples and clear the trigger status.
acquisition_en: in std_logic;
-- Trigger delay in clock cycles.
trigger_delay: in std_logic_vector(15 downto 0);
-- Number of decimated samples per trigger minus 1.
record_length: in std_logic_vector(15 downto 0);
-- Decimation factor minus 1.
decimation_factor: in std_logic_vector(17 downto 0);
-- High to sum input samples; low to select single samples.
averaging: in std_logic;
-- Number of right-shift steps to apply to ADC data.
-- When set to zero, the least significant ADC sample bit aligns
-- with the least significant decimated sample bit.
shift_steps: in std_logic_vector(3 downto 0);
-- High to enable 4-channel mode.
-- Ignored if num_channels == 2.
ch4_mode: in std_logic;
-- High to enable automatic (continuous) triggering.
trig_auto_en: in std_logic;
-- High to enable external triggering.
trig_ext_en: in std_logic;
-- High to force a trigger event (if the acquisition chain is ready).
trig_force: in std_logic;
-- Select external input signal to use as trigger.
trig_ext_select: in std_logic_vector(1 downto 0);
-- High to trigger on falling edge, low to trigger on rising edge.
trig_ext_falling: in std_logic;
-- Global timestamp counter.
timestamp_in: in std_logic_vector(timestamp_bits - 1 downto 0);
-- ADC input data.
adc_data_in: in adc_data_array(0 to num_channels - 1);
-- External trigger signals, already synchronized and de-glitched.
trig_ext_in: in std_logic_vector(3 downto 0);
-- High if the acquisition chain is waiting for a trigger.
trig_waiting: out std_logic;
-- Output data stream.
out_valid: out std_logic;
out_ready: in std_logic;
out_empty: in std_logic;
out_data: out dma_data_type
);
end entity;
architecture arch of acquisition_chain is
-- Number of data bits for accumulating ADC samples when averaging.
constant accum_data_bits: natural := 32;
subtype accum_data_type is std_logic_vector(accum_data_bits - 1 downto 0);
type accum_data_array is array(natural range <>) of accum_data_type;
signal s_trigger: std_logic;
signal s_trig_ack: std_logic;
signal s_sample_start: std_logic;
signal s_sample_integrate: std_logic;
signal s_sample_done: std_logic;
signal s_adc_sample: adc_data_array(0 to num_channels - 1);
signal s_adc_shifted: accum_data_array(0 to num_channels - 1);
signal s_sample_decimated: sample_data_array(0 to num_channels - 1);
begin
-- External trigger detector.
inst_trigger_detector: entity work.trigger_detector
port map (
clk => clk,
reset => reset,
trig_auto_en => trig_auto_en,
trig_ext_en => trig_ext_en,
trig_force => trig_force,
trig_select => trig_ext_select,
trig_falling => trig_ext_falling,
trig_ext_in => trig_ext_in,
trig_out => s_trigger );
-- Timing of sampling and decimation.
inst_acquisition_manager: entity work.acquisition_manager
port map (
clk => clk,
reset => reset,
acquisition_en => acquisition_en,
trigger_delay => trigger_delay,
record_length => record_length,
decimation_factor => decimation_factor,
averaging => averaging,
trig_in => s_trigger,
trig_waiting => trig_waiting,
trig_ack => s_trig_ack,
sample_start => s_sample_start,
sample_integrate => s_sample_integrate,
sample_done => s_sample_done );
-- Shift and decimation chains for each ADC channel.
inst_channels: for i in 0 to num_channels - 1 generate
inst_shift: entity work.shift_engine
generic map (
input_data_bits => adc_data_bits,
output_data_bits => accum_data_bits,
pre_shift_left => accum_data_bits - sample_data_bits,
signed_data => false )
port map (
clk => clk,
in_data => adc_data_in(i),
in_shift => shift_steps,
out_data => s_adc_shifted(i) );
inst_decimation: entity work.sample_decimation
generic map (
input_data_bits => accum_data_bits,
output_data_bits => sample_data_bits )
port map (
clk => clk,
reset => reset,
start => s_sample_start,
integrate => s_sample_integrate,
in_data => s_adc_shifted(i),
out_data => s_sample_decimated(i) );
end generate;
-- Format sample data stream and insert trigger timestamps.
inst_stream: entity work.acquisition_stream
generic map (
num_channels => num_channels )
port map (
clk => clk,
reset => reset,
ch4_mode => ch4_mode,
timestamp_in => timestamp_in,
trig_ack => s_trig_ack,
sample_valid => s_sample_done,
sample_data => s_sample_decimated,
out_valid => out_valid,
out_ready => out_ready,
out_empty => out_empty,
out_data => out_data );
end architecture;