From a984e1c8ff5e2805f01e4da7743e87cb441a5a5c Mon Sep 17 00:00:00 2001 From: Joris van Rantwijk Date: Tue, 24 Sep 2024 20:51:02 +0200 Subject: [PATCH] Add external trigger-once mode --- doc/fpga_firmware.md | 3 +++ fpga/rtl/acquisition_chain.vhd | 10 ++++++++++ fpga/rtl/puzzlefw_pkg.vhd | 5 ++++- fpga/rtl/puzzlefw_top.vhd | 2 ++ fpga/rtl/registers.vhd | 7 +++++++ fpga/rtl/trigger_detector.vhd | 5 ++++- 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/doc/fpga_firmware.md b/doc/fpga_firmware.md index d998ca5..2f6984f 100644 --- a/doc/fpga_firmware.md +++ b/doc/fpga_firmware.md @@ -577,6 +577,7 @@ Trigger configuration. |---------|---------------|--------|-------------| | 0 | trig_auto_en | RW | '1' to enable auto-trigger mode. | | 1 | trig_ext_en | RW | '1' to enable external triggering. | +| 2 | trig_ext_once | RW | '1' to accept one external trigger. | | 5 : 4 | trig_ext_select | RW | Select digital input channel to use as external trigger. | | 7 | trig_ext_falling | RW | '1' to trigger on falling edge, '0' to trigger on rising edge. | | 8 | trig_force | WC | Write '1' to force a single trigger event. | @@ -584,6 +585,8 @@ Trigger configuration. Auto-trigger mode takes precedence over external triggering. If auto-triggering and external triggering are both disabled, no data acquisition takes place unless a trigger is forced by writing to `trig_force`. +External triggering is enabled if either `trig_ext_en` or `trig_ext_once` is set. If any trigger occurs (regardless of trigger source), `trig_ext_once` is cleared automatically. + ### 0x000244: TRIGGER_DELAY Trigger delay. diff --git a/fpga/rtl/acquisition_chain.vhd b/fpga/rtl/acquisition_chain.vhd index bf0e9f3..b71929f 100644 --- a/fpga/rtl/acquisition_chain.vhd +++ b/fpga/rtl/acquisition_chain.vhd @@ -60,6 +60,9 @@ entity acquisition_chain is -- High to enable external triggering. trig_ext_en: in std_logic; + -- High to accept one external trigger. + trig_ext_once: in std_logic; + -- High to force a trigger event (if the acquisition chain is ready). trig_force: in std_logic; @@ -81,6 +84,9 @@ entity acquisition_chain is -- High if the acquisition chain is waiting for a trigger. trig_waiting: out std_logic; + -- High for one cycle if a trigger is detected. + trig_detected: out std_logic; + -- Output data stream. out_valid: out std_logic; out_ready: in std_logic; @@ -109,6 +115,9 @@ architecture arch of acquisition_chain is begin + -- Expose trigger signal. + trig_detected <= s_trigger; + -- External trigger detector. inst_trigger_detector: entity work.trigger_detector port map ( @@ -116,6 +125,7 @@ begin reset => reset, trig_auto_en => trig_auto_en, trig_ext_en => trig_ext_en, + trig_ext_once => trig_ext_once, trig_force => trig_force, trig_select => trig_ext_select, trig_falling => trig_ext_falling, diff --git a/fpga/rtl/puzzlefw_pkg.vhd b/fpga/rtl/puzzlefw_pkg.vhd index 3c29828..3176ea9 100644 --- a/fpga/rtl/puzzlefw_pkg.vhd +++ b/fpga/rtl/puzzlefw_pkg.vhd @@ -94,7 +94,7 @@ package puzzlefw_pkg is -- Firmware info word. constant fw_api_version: natural := 1; constant fw_version_major: natural := 0; - constant fw_version_minor: natural := 9; + constant fw_version_minor: natural := 10; constant fw_info_word: std_logic_vector(31 downto 0) := x"4a" & std_logic_vector(to_unsigned(fw_api_version, 8)) @@ -131,6 +131,7 @@ package puzzlefw_pkg is simulate_adc: std_logic; trig_auto_en: std_logic; trig_ext_en: std_logic; + trig_ext_once: std_logic; trig_force: std_logic; -- single cycle trig_ext_select: std_logic_vector(1 downto 0); trig_ext_falling: std_logic; @@ -165,6 +166,7 @@ package puzzlefw_pkg is acq_addr_ptr: std_logic_vector(31 downto 3); acq_dma_busy: std_logic; trig_waiting: std_logic; + trig_detected: std_logic; adc_sample: adc_data_array(0 to 3); adc_min_value: adc_data_array(0 to 3); adc_max_value: adc_data_array(0 to 3); @@ -195,6 +197,7 @@ package puzzlefw_pkg is simulate_adc => '0', trig_auto_en => '0', trig_ext_en => '0', + trig_ext_once => '0', trig_force => '0', trig_ext_select => (others => '0'), trig_ext_falling => '0', diff --git a/fpga/rtl/puzzlefw_top.vhd b/fpga/rtl/puzzlefw_top.vhd index 38330aa..393aef6 100644 --- a/fpga/rtl/puzzlefw_top.vhd +++ b/fpga/rtl/puzzlefw_top.vhd @@ -504,6 +504,7 @@ begin 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, + trig_ext_once => s_reg_control.trig_ext_once, 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, @@ -511,6 +512,7 @@ begin adc_data_in => s_adc_sample, trig_ext_in => s_dig_sample, trig_waiting => s_reg_status.trig_waiting, + trig_detected => s_reg_status.trig_detected, out_valid => s_acq_dma_valid, out_ready => s_acq_dma_ready, out_empty => s_acq_dma_empty, diff --git a/fpga/rtl/registers.vhd b/fpga/rtl/registers.vhd index 8e80f68..c85ecd1 100644 --- a/fpga/rtl/registers.vhd +++ b/fpga/rtl/registers.vhd @@ -85,6 +85,11 @@ begin v.reg_control.tt_intr_clear := '0'; v.reg_control.timetagger_mark := '0'; + -- Clear trigger-once flag when a trigger occurs. + if reg_status.trig_detected = '1' then + v.reg_control.trig_ext_once := '0'; + end if; + -- Respond to each APB access on the next clock cycle (no wait states). v.pready := apb_psel and (not apb_penable); @@ -130,6 +135,7 @@ begin when reg_trigger_mode => v.prdata(0) := r.reg_control.trig_auto_en; v.prdata(1) := r.reg_control.trig_ext_en; + v.prdata(2) := r.reg_control.trig_ext_once; v.prdata(5 downto 4) := r.reg_control.trig_ext_select; v.prdata(7) := r.reg_control.trig_ext_falling; when reg_trigger_delay => v.prdata(15 downto 0) := r.reg_control.trigger_delay; @@ -203,6 +209,7 @@ begin when reg_trigger_mode => v.reg_control.trig_auto_en := apb_pwdata(0); v.reg_control.trig_ext_en := apb_pwdata(1); + v.reg_control.trig_ext_once := apb_pwdata(2); v.reg_control.trig_ext_select := apb_pwdata(5 downto 4); v.reg_control.trig_ext_falling := apb_pwdata(7); v.reg_control.trig_force := apb_pwdata(8); diff --git a/fpga/rtl/trigger_detector.vhd b/fpga/rtl/trigger_detector.vhd index 9ebe2d2..0f5ee03 100644 --- a/fpga/rtl/trigger_detector.vhd +++ b/fpga/rtl/trigger_detector.vhd @@ -26,6 +26,9 @@ entity trigger_detector is -- High to enable external triggering. trig_ext_en: in std_logic; + -- High to accept one external trigger. + trig_ext_once: in std_logic; + -- High to force a trigger event (if the acquisition chain is ready). trig_force: in std_logic; @@ -78,7 +81,7 @@ begin -- Combine trigger sources. v.trig_out := trig_auto_en or - (trig_ext_en and r.ext_trig) or + ((trig_ext_en or trig_ext_once) and r.ext_trig) or trig_force; -- Synchronous reset.