189 lines
6.7 KiB
VHDL
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;
|