redpitaya-puzzlefw/fpga/rtl/puzzlefw_top.vhd

595 lines
25 KiB
VHDL
Raw Normal View History

2024-08-02 21:47:58 +02:00
--
-- Top-level FPGA design for Red Pitaya PuzzleFW firmware.
--
-- Joris van Rantwijk 2024
--
library ieee;
use ieee.std_logic_1164.all;
2024-08-09 20:16:53 +02:00
use ieee.std_logic_misc.all;
2024-08-02 21:47:58 +02:00
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
library xpm;
use xpm.vcomponents.all;
use work.puzzlefw_pkg.all;
entity puzzlefw_top is
port (
-- Ports directly connected to ARM/PS.
DDR_0_addr: inout std_logic_vector(14 downto 0);
DDR_0_ba: inout std_logic_vector(2 downto 0);
DDR_0_cas_n: inout std_logic;
DDR_0_ck_n: inout std_logic;
DDR_0_ck_p: inout std_logic;
DDR_0_cke: inout std_logic;
DDR_0_cs_n: inout std_logic;
DDR_0_dm: inout std_logic_vector(3 downto 0);
DDR_0_dq: inout std_logic_vector(31 downto 0);
DDR_0_dqs_n: inout std_logic_vector(3 downto 0);
DDR_0_dqs_p: inout std_logic_vector(3 downto 0);
DDR_0_odt: inout std_logic;
DDR_0_ras_n: inout std_logic;
DDR_0_reset_n: inout std_logic;
DDR_0_we_n: inout std_logic;
FIXED_IO_0_ddr_vrn: inout std_logic;
FIXED_IO_0_ddr_vrp: inout std_logic;
FIXED_IO_0_mio: inout std_logic_vector(53 downto 0);
FIXED_IO_0_ps_clk: inout std_logic;
FIXED_IO_0_ps_porb: inout std_logic;
FIXED_IO_0_ps_srstb: inout std_logic;
-- Ports controlled by FPGA.
adc_dat_i: in adc_data_input_type; -- ADC data
adc_clk_i: in std_logic_vector(1 downto 0); -- ADC clock 1=pos, 0=neg
adc_clk_o: out std_logic_vector(1 downto 0); -- optional clock output for ADC
adc_cdcs_o: out std_logic; -- ADC clock duty cycle stabilizer
dac_dat_o: out std_logic_vector(13 downto 0); -- DAC data
dac_wrt_o: out std_logic; -- DAC write control
dac_sel_o: out std_logic; -- DAC channel select
dac_clk_o: out std_logic; -- DAC clock
dac_rst_o: out std_logic; -- DAC reset
dac_pwm_o: out std_logic_vector(3 downto 0); -- PWM DAC
exp_p_io: inout std_logic_vector(7 downto 0); -- extension I/O pos
exp_n_io: inout std_logic_vector(7 downto 0); -- extension I/O neg
2024-08-30 23:04:02 +02:00
led_o: out std_logic_vector(7 downto 0) -- LEDs
2024-08-02 21:47:58 +02:00
);
end puzzlefw_top;
architecture arch of puzzlefw_top is
-- Main 125 MHz clock, derived from ADC clock input port.
signal clk_adc: std_logic;
-- Auxiliary clock from FCLK0.
signal clk_fclk: std_logic;
-- Main reset signal, derived from FCLK_RESET0, active high, synchronous to clk_adc.
signal s_reset: std_logic;
2024-08-26 12:52:35 +02:00
-- Internal clock signal.
2024-08-02 21:47:58 +02:00
signal s_adc_clk_ibuf: std_logic;
2024-08-26 12:52:35 +02:00
2024-08-27 23:48:12 +02:00
-- Blinking LED.
signal r_adcclk_cnt: unsigned(25 downto 0);
2024-08-02 21:47:58 +02:00
signal r_adcclk_led: std_logic;
2024-08-27 23:48:12 +02:00
-- APB bus for register access.
2024-08-02 21:47:58 +02:00
signal s_apb_paddr: std_logic_vector(31 downto 0);
signal s_apb_penable: std_logic;
signal s_apb_prdata: std_logic_vector(31 downto 0);
signal s_apb_pready: std_logic;
signal s_apb_psel: std_logic;
signal s_apb_pslverr: std_logic;
signal s_apb_pwdata: std_logic_vector(31 downto 0);
signal s_apb_pwrite: std_logic;
2024-08-27 23:48:12 +02:00
-- AXI bus for DMA.
2024-08-02 21:47:58 +02:00
signal s_axi_awid: std_logic_vector(5 downto 0);
signal s_axi_awaddr: std_logic_vector(31 downto 0);
signal s_axi_awlen: std_logic_vector(3 downto 0);
signal s_axi_awsize: std_logic_vector(2 downto 0);
signal s_axi_awburst: std_logic_vector(1 downto 0);
signal s_axi_awlock: std_logic_vector(1 downto 0);
signal s_axi_awcache: std_logic_vector(3 downto 0);
signal s_axi_awprot: std_logic_vector(2 downto 0);
signal s_axi_awqos: std_logic_vector(3 downto 0);
signal s_axi_awvalid: std_logic;
signal s_axi_awready: std_logic;
signal s_axi_wid: std_logic_vector(5 downto 0);
signal s_axi_wdata: std_logic_vector(63 downto 0);
signal s_axi_wstrb: std_logic_vector(7 downto 0);
signal s_axi_wlast: std_logic;
signal s_axi_wvalid: std_logic;
signal s_axi_wready: std_logic;
signal s_axi_bid: std_logic_vector(5 downto 0);
signal s_axi_bresp: std_logic_vector(1 downto 0);
signal s_axi_bvalid: std_logic;
signal s_axi_bready: std_logic;
signal s_axi_arid: std_logic_vector(5 downto 0);
signal s_axi_araddr: std_logic_vector(31 downto 0);
signal s_axi_arlen: std_logic_vector(3 downto 0);
signal s_axi_arsize: std_logic_vector(2 downto 0);
signal s_axi_arburst: std_logic_vector(1 downto 0);
signal s_axi_arlock: std_logic_vector(1 downto 0);
signal s_axi_arcache: std_logic_vector(3 downto 0);
signal s_axi_arprot: std_logic_vector(2 downto 0);
signal s_axi_arqos: std_logic_vector(3 downto 0);
signal s_axi_arvalid: std_logic;
signal s_axi_arready: std_logic;
signal s_axi_rid: std_logic_vector(5 downto 0);
signal s_axi_rdata: std_logic_vector(63 downto 0);
signal s_axi_rresp: std_logic_vector(1 downto 0);
signal s_axi_rlast: std_logic;
signal s_axi_rvalid: std_logic;
signal s_axi_rready: std_logic;
2024-08-27 23:48:12 +02:00
-- Interrupts.
2024-08-30 23:04:02 +02:00
signal s_irq_pending: std_logic_vector(1 downto 0);
2024-08-09 20:16:53 +02:00
signal s_irq_f2p: std_logic_vector(7 downto 0);
2024-08-02 21:47:58 +02:00
2024-08-27 23:48:12 +02:00
-- Registers.
2024-08-02 21:47:58 +02:00
signal s_reg_control: registers_control;
signal s_reg_status: registers_status;
2024-08-27 23:48:12 +02:00
-- DMA write channel control.
2024-08-30 23:04:02 +02:00
signal s_dma_write_cmd_addr: dma_address_array(0 to 1);
signal s_dma_write_cmd_length: dma_burst_length_array(0 to 1);
signal s_dma_write_cmd_valid: std_logic_vector(1 downto 0);
signal s_dma_write_cmd_ready: std_logic_vector(1 downto 0);
signal s_dma_write_data: dma_data_array(0 to 1);
signal s_dma_write_data_ready: std_logic_vector(1 downto 0);
signal s_dma_write_finished: std_logic_vector(1 downto 0);
2024-08-09 20:16:53 +02:00
signal s_acq_dma_valid: std_logic;
signal s_acq_dma_ready: std_logic;
signal s_acq_dma_empty: std_logic;
signal s_acq_dma_data: dma_data_type;
2024-08-02 21:47:58 +02:00
2024-08-30 23:04:02 +02:00
signal s_tt_dma_valid: std_logic;
signal s_tt_dma_ready: std_logic;
signal s_tt_dma_empty: std_logic;
signal s_tt_dma_data: dma_data_type;
2024-08-27 23:48:12 +02:00
signal s_timestamp: std_logic_vector(timestamp_bits - 1 downto 0);
signal s_adc_data: adc_data_array(0 to 1);
signal s_adc_sample: adc_data_array(0 to 1);
signal s_dig_in: std_logic_vector(3 downto 0);
signal s_dig_sync: std_logic_vector(3 downto 0);
signal s_dig_deglitch: std_logic_vector(3 downto 0);
signal s_dig_sample: std_logic_vector(3 downto 0);
2024-08-02 21:47:58 +02:00
begin
2024-08-28 00:58:27 +02:00
-- Drive LEDs.
2024-08-27 23:48:12 +02:00
led_o(0) <= r_adcclk_led; -- blinking LED, 1 Hz
led_o(1) <= s_reg_control.acquisition_en; -- acquisition enabled
led_o(2) <= s_reg_status.trig_waiting; -- waiting for trigger
2024-08-30 23:04:02 +02:00
led_o(3) <= or_reduce(s_reg_control.timetagger_en); -- timetagger enabled
2024-08-27 23:48:12 +02:00
led_o(7 downto 4) <= s_reg_control.led_state(7 downto 4);
2024-08-02 21:47:58 +02:00
2024-08-28 00:58:27 +02:00
-- Enable ADC clock duty cycle stabilizer.
adc_cdcs_o <= '1';
-- ADC clock outputs are not connected on vanilla Red Pitaya 125-14.
adc_clk_o <= (others => 'Z');
-- Drive safe levels to unused DAC pins.
dac_dat_o <= (others => '0');
dac_wrt_o <= '0';
dac_sel_o <= '0';
dac_clk_o <= '0';
dac_rst_o <= '0';
dac_pwm_o <= (others => 'Z');
2024-08-30 23:04:02 +02:00
-- Use extension I/O pins as inputs only.
2024-08-31 13:17:22 +02:00
exp_p_io <= (others => 'Z');
2024-08-28 00:58:27 +02:00
exp_n_io <= (others => 'Z');
2024-08-02 21:47:58 +02:00
-- Differential clock input for ADC clock.
inst_ibuf_adc_clk: IBUFDS
port map (
O => s_adc_clk_ibuf,
I => adc_clk_i(1),
IB => adc_clk_i(0)
);
-- Clock buffer for ADC clock.
inst_bufg_adc_clk: BUFG
port map (
I => s_adc_clk_ibuf,
O => clk_adc
);
-- ARM/PS block design.
inst_blockdesign: entity work.puzzlefw_wrapper
port map (
sys_clk => clk_adc,
ps_fclk => clk_fclk,
peripheral_reset_0(0) => s_reset,
DDR_0_addr => DDR_0_addr,
DDR_0_ba => DDR_0_ba,
DDR_0_cas_n => DDR_0_cas_n,
DDR_0_ck_n => DDR_0_ck_n,
DDR_0_ck_p => DDR_0_ck_p,
DDR_0_cke => DDR_0_cke,
DDR_0_cs_n => DDR_0_cs_n,
DDR_0_dm => DDR_0_dm,
DDR_0_dq => DDR_0_dq,
DDR_0_dqs_n => DDR_0_dqs_n,
DDR_0_dqs_p => DDR_0_dqs_p,
DDR_0_odt => DDR_0_odt,
DDR_0_ras_n => DDR_0_ras_n,
DDR_0_reset_n => DDR_0_reset_n,
DDR_0_we_n => DDR_0_we_n,
FIXED_IO_0_ddr_vrn => FIXED_IO_0_ddr_vrn,
FIXED_IO_0_ddr_vrp => FIXED_IO_0_ddr_vrp,
FIXED_IO_0_mio => FIXED_IO_0_mio,
FIXED_IO_0_ps_clk => FIXED_IO_0_ps_clk,
FIXED_IO_0_ps_porb => FIXED_IO_0_ps_porb,
FIXED_IO_0_ps_srstb => FIXED_IO_0_ps_srstb,
APB_M_0_paddr => s_apb_paddr,
APB_M_0_penable => s_apb_penable,
APB_M_0_prdata => s_apb_prdata,
APB_M_0_pready(0) => s_apb_pready,
APB_M_0_psel(0) => s_apb_psel,
APB_M_0_pslverr(0) => s_apb_pslverr,
APB_M_0_pwdata => s_apb_pwdata,
APB_M_0_pwrite => s_apb_pwrite,
2024-08-09 20:16:53 +02:00
IRQ_F2P => s_irq_f2p,
2024-08-02 21:47:58 +02:00
S_AXI_HP0_0_araddr => s_axi_araddr,
S_AXI_HP0_0_arburst => s_axi_arburst,
S_AXI_HP0_0_arcache => s_axi_arcache,
S_AXI_HP0_0_arid => s_axi_arid,
S_AXI_HP0_0_arlen => s_axi_arlen,
S_AXI_HP0_0_arlock => s_axi_arlock,
S_AXI_HP0_0_arprot => s_axi_arprot,
S_AXI_HP0_0_arqos => s_axi_arqos,
S_AXI_HP0_0_arready => s_axi_arready,
S_AXI_HP0_0_arsize => s_axi_arsize,
S_AXI_HP0_0_arvalid => s_axi_arvalid,
S_AXI_HP0_0_awaddr => s_axi_awaddr,
S_AXI_HP0_0_awburst => s_axi_awburst,
S_AXI_HP0_0_awcache => s_axi_awcache,
S_AXI_HP0_0_awid => s_axi_awid,
S_AXI_HP0_0_awlen => s_axi_awlen,
S_AXI_HP0_0_awlock => s_axi_awlock,
S_AXI_HP0_0_awprot => s_axi_awprot,
S_AXI_HP0_0_awqos => s_axi_awqos,
S_AXI_HP0_0_awready => s_axi_awready,
S_AXI_HP0_0_awsize => s_axi_awsize,
S_AXI_HP0_0_awvalid => s_axi_awvalid,
S_AXI_HP0_0_bid => s_axi_bid,
S_AXI_HP0_0_bready => s_axi_bready,
S_AXI_HP0_0_bresp => s_axi_bresp,
S_AXI_HP0_0_bvalid => s_axi_bvalid,
S_AXI_HP0_0_rdata => s_axi_rdata,
S_AXI_HP0_0_rid => s_axi_rid,
S_AXI_HP0_0_rlast => s_axi_rlast,
S_AXI_HP0_0_rready => s_axi_rready,
S_AXI_HP0_0_rresp => s_axi_rresp,
S_AXI_HP0_0_rvalid => s_axi_rvalid,
S_AXI_HP0_0_wdata => s_axi_wdata,
S_AXI_HP0_0_wid => s_axi_wid,
S_AXI_HP0_0_wlast => s_axi_wlast,
S_AXI_HP0_0_wready => s_axi_wready,
S_AXI_HP0_0_wstrb => s_axi_wstrb,
S_AXI_HP0_0_wvalid => s_axi_wvalid
);
-- Memory-mapped registers.
inst_registers: entity work.registers
generic map (
num_acq_channels => 2 )
2024-08-02 21:47:58 +02:00
port map (
clk => clk_adc,
reset => s_reset,
apb_psel => s_apb_psel,
apb_penable => s_apb_penable,
apb_pwrite => s_apb_pwrite,
apb_paddr => s_apb_paddr,
apb_pwdata => s_apb_pwdata,
apb_pready => s_apb_pready,
apb_pslverr => s_apb_pslverr,
apb_prdata => s_apb_prdata,
reg_control => s_reg_control,
2024-08-26 12:52:35 +02:00
reg_status => s_reg_status
2024-08-02 21:47:58 +02:00
);
-- AXI master.
inst_axi_master: entity work.dma_axi_master
generic map (
2024-08-09 20:16:53 +02:00
num_read_channels => 0,
2024-08-30 23:04:02 +02:00
num_write_channels => 2 )
2024-08-02 21:47:58 +02:00
port map (
clk => clk_adc,
reset => s_reset,
dma_en => s_reg_control.dma_en,
dma_busy => s_reg_status.dma_busy,
window_base_addr => s_reg_control.dma_buf_addr,
window_size => s_reg_control.dma_buf_size,
err_read => s_reg_status.dma_err_read,
err_write => s_reg_status.dma_err_write,
err_address => s_reg_status.dma_err_address,
err_any => s_reg_status.dma_err_any,
2024-08-26 12:52:35 +02:00
clear_errors => s_reg_control.dma_clear,
2024-08-09 20:16:53 +02:00
read_cmd_addr => (others => (others => '0')),
read_cmd_length => (others => (others => '0')),
2024-08-09 20:16:53 +02:00
read_cmd_valid => (others => '0'),
read_cmd_ready => open,
read_data => open,
read_data_valid => open,
write_cmd_addr => s_dma_write_cmd_addr,
write_cmd_length => s_dma_write_cmd_length,
2024-08-09 20:16:53 +02:00
write_cmd_valid => s_dma_write_cmd_valid,
write_cmd_ready => s_dma_write_cmd_ready,
write_data => s_dma_write_data,
write_data_ready => s_dma_write_data_ready,
write_finished => s_dma_write_finished,
2024-08-02 21:47:58 +02:00
m_axi_awid => s_axi_awid,
m_axi_awaddr => s_axi_awaddr,
m_axi_awlen => s_axi_awlen,
m_axi_awsize => s_axi_awsize,
m_axi_awburst => s_axi_awburst,
m_axi_awlock => s_axi_awlock,
m_axi_awcache => s_axi_awcache,
m_axi_awprot => s_axi_awprot,
m_axi_awqos => s_axi_awqos,
m_axi_awvalid => s_axi_awvalid,
m_axi_awready => s_axi_awready,
m_axi_wid => s_axi_wid,
m_axi_wdata => s_axi_wdata,
m_axi_wstrb => s_axi_wstrb,
m_axi_wlast => s_axi_wlast,
m_axi_wvalid => s_axi_wvalid,
m_axi_wready => s_axi_wready,
m_axi_bid => s_axi_bid,
m_axi_bresp => s_axi_bresp,
m_axi_bvalid => s_axi_bvalid,
m_axi_bready => s_axi_bready,
m_axi_arid => s_axi_arid,
m_axi_araddr => s_axi_araddr,
m_axi_arlen => s_axi_arlen,
m_axi_arsize => s_axi_arsize,
m_axi_arburst => s_axi_arburst,
m_axi_arlock => s_axi_arlock,
m_axi_arcache => s_axi_arcache,
m_axi_arprot => s_axi_arprot,
m_axi_arqos => s_axi_arqos,
m_axi_arvalid => s_axi_arvalid,
m_axi_arready => s_axi_arready,
m_axi_rid => s_axi_rid,
m_axi_rdata => s_axi_rdata,
m_axi_rresp => s_axi_rresp,
m_axi_rlast => s_axi_rlast,
m_axi_rvalid => s_axi_rvalid,
m_axi_rready => s_axi_rready
);
2024-08-30 23:04:02 +02:00
-- DMA write channel for analog acquisition
inst_acq_dma: entity work.dma_write_channel
2024-08-02 21:47:58 +02:00
generic map (
transfer_size_bits => 4,
queue_size_bits => 14,
idle_timeout => 256 )
2024-08-02 21:47:58 +02:00
port map (
2024-08-09 20:16:53 +02:00
clk => clk_adc,
reset => s_reset,
channel_en => s_reg_control.acq_dma_en,
channel_busy => s_reg_status.acq_dma_busy,
channel_init => s_reg_control.acq_dma_init,
2024-08-09 20:16:53 +02:00
addr_start => s_reg_control.acq_addr_start,
addr_end => s_reg_control.acq_addr_end,
addr_limit => s_reg_control.acq_addr_limit,
addr_interrupt => s_reg_control.acq_addr_intr,
addr_pointer => s_reg_status.acq_addr_ptr,
intr_en => s_reg_control.acq_intr_en,
2024-08-26 12:52:35 +02:00
intr_clear => s_reg_control.acq_intr_clear,
intr_out => s_irq_pending(0),
in_valid => s_acq_dma_valid,
in_ready => s_acq_dma_ready,
in_empty => s_acq_dma_empty,
in_data => s_acq_dma_data,
2024-08-09 20:16:53 +02:00
write_cmd_addr => s_dma_write_cmd_addr(0),
write_cmd_length => s_dma_write_cmd_length(0),
2024-08-09 20:16:53 +02:00
write_cmd_valid => s_dma_write_cmd_valid(0),
write_cmd_ready => s_dma_write_cmd_ready(0),
write_data => s_dma_write_data(0),
write_data_ready => s_dma_write_data_ready(0),
write_finished => s_dma_write_finished(0) );
2024-08-30 23:04:02 +02:00
-- DMA write channel for time tagger
inst_tt_dma: entity work.dma_write_channel
generic map (
transfer_size_bits => 4,
queue_size_bits => 12,
2024-08-30 23:04:02 +02:00
idle_timeout => 256 )
port map (
clk => clk_adc,
reset => s_reset,
channel_en => s_reg_control.tt_dma_en,
channel_busy => s_reg_status.tt_dma_busy,
channel_init => s_reg_control.tt_dma_init,
addr_start => s_reg_control.tt_addr_start,
addr_end => s_reg_control.tt_addr_end,
addr_limit => s_reg_control.tt_addr_limit,
addr_interrupt => s_reg_control.tt_addr_intr,
addr_pointer => s_reg_status.tt_addr_ptr,
intr_en => s_reg_control.tt_intr_en,
intr_clear => s_reg_control.tt_intr_clear,
intr_out => s_irq_pending(1),
in_valid => s_tt_dma_valid,
in_ready => s_tt_dma_ready,
in_empty => s_tt_dma_empty,
in_data => s_tt_dma_data,
write_cmd_addr => s_dma_write_cmd_addr(1),
write_cmd_length => s_dma_write_cmd_length(1),
write_cmd_valid => s_dma_write_cmd_valid(1),
write_cmd_ready => s_dma_write_cmd_ready(1),
write_data => s_dma_write_data(1),
write_data_ready => s_dma_write_data_ready(1),
write_finished => s_dma_write_finished(1) );
2024-08-26 12:52:35 +02:00
-- Timestamp generator.
inst_timestamp_gen: entity work.timestamp_gen
port map (
clk => clk_adc,
reset => s_reset,
clear => s_reg_control.timestamp_clear,
timestamp => s_timestamp );
s_reg_status.timestamp <= s_timestamp;
-- Capture ADC data.
-- Ignore the 2 LSB bits which are not-connected on the ADC side.
inst_capture_gen: for i in 0 to 1 generate
inst_adc_capture: entity work.adc_capture
port map (
clk => clk_adc,
in_data => adc_dat_i(i)(15 downto 2),
out_data => s_adc_data(i) );
end generate;
-- Optionally generate simulated ADC samples.
inst_adc_sample_stream: entity work.adc_sample_stream
2024-08-26 12:52:35 +02:00
port map (
clk => clk_adc,
reset => s_reset,
simulate => s_reg_control.simulate_adc,
in_data => s_adc_data(0 to 1),
out_data => s_adc_sample(0 to 1) );
-- Monitor range of ADC samples.
inst_monitor_gen: for i in 0 to 1 generate
inst_range_monitor: entity work.adc_range_monitor
generic map (
signed_data => false )
port map (
clk => clk_adc,
reset => s_reset,
clear => s_reg_control.adc_range_clear,
in_data => s_adc_sample(i),
min_value => s_reg_status.adc_min_value(i),
max_value => s_reg_status.adc_max_value(i) );
end generate;
-- Monitor current ADC sample value.
s_reg_status.adc_sample(0 to 1) <= s_adc_sample(0 to 1);
-- Drive dummy values to not-implemented channels 2, 3.
s_reg_status.adc_sample(2 to 3) <= (others => (others => '0'));
s_reg_status.adc_min_value(2 to 3) <= (others => (others => '0'));
s_reg_status.adc_max_value(2 to 3) <= (others => (others => '0'));
2024-08-26 12:52:35 +02:00
-- Analog acquisition data chain.
inst_acquisition_chain: entity work.acquisition_chain
generic map (
num_channels => 2 )
port map (
clk => clk_adc,
reset => s_reset,
acquisition_en => s_reg_control.acquisition_en,
trigger_delay => s_reg_control.trigger_delay,
record_length => s_reg_control.record_length,
decimation_factor => s_reg_control.decimation_factor,
averaging => s_reg_control.averaging_en,
shift_steps => s_reg_control.shift_steps,
ch4_mode => s_reg_control.ch4_mode,
trig_auto_en => s_reg_control.trig_auto_en,
trig_ext_en => s_reg_control.trig_ext_en,
2024-09-24 20:51:02 +02:00
trig_ext_once => s_reg_control.trig_ext_once,
2024-08-26 12:52:35 +02:00
trig_force => s_reg_control.trig_force,
trig_ext_select => s_reg_control.trig_ext_select,
trig_ext_falling => s_reg_control.trig_ext_falling,
timestamp_in => s_timestamp,
adc_data_in => s_adc_sample,
2024-08-30 23:04:02 +02:00
trig_ext_in => s_dig_sample,
2024-08-26 12:52:35 +02:00
trig_waiting => s_reg_status.trig_waiting,
2024-09-24 20:51:02 +02:00
trig_detected => s_reg_status.trig_detected,
2024-08-26 12:52:35 +02:00
out_valid => s_acq_dma_valid,
out_ready => s_acq_dma_ready,
out_empty => s_acq_dma_empty,
out_data => s_acq_dma_data );
2024-08-27 23:48:12 +02:00
-- Capture digital inputs.
s_dig_in(0) <= exp_p_io(0);
s_dig_in(1) <= exp_n_io(0);
s_dig_in(2) <= exp_p_io(1);
s_dig_in(3) <= exp_n_io(1);
2024-08-02 21:47:58 +02:00
2024-08-27 23:48:12 +02:00
inst_dig_capture_gen: for i in 0 to 3 generate
-- Use a 2-flipflop synchronizer to avoid metastability.
inst_dig_sync: entity work.syncdff
port map (
clk => clk_adc,
di => s_dig_in(i),
do => s_dig_sync(i) );
-- Deglitch filter.
inst_dig_deglitch: entity work.deglitch
generic map (
deglitch_cycles => 4 )
port map (
clk => clk_adc,
din => s_dig_sync(i),
dout => s_dig_deglitch(i) );
end generate;
-- Optionally generate simulated digital signals.
process (clk_adc) is
2024-08-02 21:47:58 +02:00
begin
2024-08-27 23:48:12 +02:00
if rising_edge(clk_adc) then
if s_reg_control.dig_simulate = '1' then
s_dig_sample <= s_reg_control.dig_sim_state;
else
s_dig_sample <= s_dig_deglitch;
end if;
2024-08-02 21:47:58 +02:00
end if;
end process;
2024-08-27 23:48:12 +02:00
-- Monitor digital signal state.
s_reg_status.dig_sample <= s_dig_sample;
2024-08-30 23:04:02 +02:00
-- Time tagger.
inst_timetagger: entity work.timetagger
port map (
clk => clk_adc,
reset => s_reset,
channel_en => s_reg_control.timetagger_en,
marker => s_reg_control.timetagger_mark,
timestamp_in => s_timestamp,
dig_sample => s_dig_sample,
out_valid => s_tt_dma_valid,
out_ready => s_tt_dma_ready,
out_empty => s_tt_dma_empty,
out_data => s_tt_dma_data );
2024-08-27 23:48:12 +02:00
-- Collect interrupt signals from peripherals and generate interrupt to PS.
s_reg_status.irq_pending <= s_irq_pending;
s_irq_f2p(0) <= s_reg_control.irq_enable and or_reduce(s_irq_pending);
s_irq_f2p(7 downto 1) <= (others => '0');
-- Blinking LED, 1 Hz.
2024-08-02 21:47:58 +02:00
process (clk_adc) is
begin
if rising_edge(clk_adc) then
2024-08-27 23:48:12 +02:00
if r_adcclk_cnt = 62499999 then
r_adcclk_cnt <= (others => '0');
r_adcclk_led <= not r_adcclk_led;
else
r_adcclk_cnt <= r_adcclk_cnt + 1;
end if;
2024-08-02 21:47:58 +02:00
end if;
end process;
end architecture;