From 8692e783f9b15a4fce5f0807336c01af21fbfefc Mon Sep 17 00:00:00 2001 From: Heyang Long <49754464+hanklong99@users.noreply.github.com> Date: Thu, 4 Jun 2026 22:47:47 +0100 Subject: [PATCH] Fixed output saturation and trigger-related bugs 1. Reset the accumulator after the completion of the current frame. 2. Updated the boxcar counter logic to prevent false triggering when no trigger events are present. 3. Fixed a minor output bug. --- .../BoxcarAveragerFullRate/vhdl/BoxcarGen.vhd | 26 +++++++++++++------ .../vhdl/Integrator2nd.vhd | 4 ++- .../BoxcarAveragerFullRate/vhdl/Top.vhd | 5 ++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/mc/Advanced/BoxcarAveragerFullRate/vhdl/BoxcarGen.vhd b/mc/Advanced/BoxcarAveragerFullRate/vhdl/BoxcarGen.vhd index 80a1188..91749ee 100644 --- a/mc/Advanced/BoxcarAveragerFullRate/vhdl/BoxcarGen.vhd +++ b/mc/Advanced/BoxcarAveragerFullRate/vhdl/BoxcarGen.vhd @@ -29,7 +29,8 @@ entity BoxcarGen is end entity; architecture Behavioral of BoxcarGen is - signal counter : unsigned(G_COUNTER_WIDTH - 1 downto 0) := (others => '1'); + signal counter : unsigned(G_COUNTER_WIDTH - 1 downto 0) := (others => '0'); + signal is_active : std_logic := '0'; constant ALL_OFF : std_logic_vector(G_NUM_SAMPLES - 1 downto 0) := (others => '0'); begin process (clk) @@ -39,13 +40,15 @@ begin variable v_current_counter_base : unsigned(G_COUNTER_WIDTH - 1 downto 0); variable v_boxcar_mask : std_logic_vector(G_NUM_SAMPLES - 1 downto 0); variable v_trg_active : std_logic; + variable v_curr_active : std_logic; variable v_base_count : unsigned(G_COUNTER_WIDTH - 1 downto 0); begin if rising_edge(clk) then v_boxcar_mask := (others => '0'); if reset = '1' then - counter <= (others => '1'); + counter <= (others => '0'); + is_active <= '0'; boxcar_out <= (others => '0'); sample_out <= (others => (others => '0')); else @@ -54,21 +57,28 @@ begin -------------------------------------------------------------------------------- -- 1. Trigger Activation and Counter Update -------------------------------------------------------------------------------- - -- If any bit in the mask is high, we treat this frame as a "Trigger Frame" - if trg_mask_in /= ALL_OFF then + -- If any bit in the mask is high AND it is idle, accept the trigger + if trg_mask_in /= ALL_OFF and is_active = '0' then v_trg_active := '1'; else v_trg_active := '0'; end if; - -- Update the registered counter for the NEXT frame + v_curr_active := is_active or v_trg_active; + + -- Update the registered counter and active flag for the NEXT frame if v_trg_active = '1' then + is_active <= '1'; -- The next frame will start counting from the remaining samples in this frame -- e.g., if 8 samples total and trg is at index 2, 6 samples pass this cycle. counter <= to_unsigned(G_NUM_SAMPLES - to_integer(trg_idx_in), G_COUNTER_WIDTH); v_base_count := (others => '0'); -- Base is 0 because we calculate relative to trg_idx_in - elsif counter > 0 and counter < v_total_limit then - counter <= counter + to_unsigned(G_NUM_SAMPLES, G_COUNTER_WIDTH); + elsif is_active = '1' then + if counter < v_total_limit then + counter <= counter + to_unsigned(G_NUM_SAMPLES, G_COUNTER_WIDTH); + else + is_active <= '0'; + end if; v_base_count := counter; else -- Idle or Finished state @@ -93,7 +103,7 @@ begin end if; -- Window Masking Logic - if (v_curr_pos >= trg_delay_in) and (v_curr_pos < v_total_limit) then + if (v_curr_active = '1') and (v_curr_pos >= trg_delay_in) and (v_curr_pos < v_total_limit) then v_boxcar_mask(i) := '1'; sample_out(i) <= sample_in(i); else diff --git a/mc/Advanced/BoxcarAveragerFullRate/vhdl/Integrator2nd.vhd b/mc/Advanced/BoxcarAveragerFullRate/vhdl/Integrator2nd.vhd index 84011c1..9ab8300 100644 --- a/mc/Advanced/BoxcarAveragerFullRate/vhdl/Integrator2nd.vhd +++ b/mc/Advanced/BoxcarAveragerFullRate/vhdl/Integrator2nd.vhd @@ -83,7 +83,8 @@ begin -- 2. Check for batch completion -- Optimization: Check pulse_count directly to avoid adder in critical path - if pulse_count >= (num_pulses_in - 1) then + -- Explicitly catch num_pulses_in = 0 to prevent 65536-pulse accumulation + if (num_pulses_in = 0) or (pulse_count >= (num_pulses_in - 1)) then v_batch_done := true; else v_next_count := pulse_count + 1; @@ -101,6 +102,7 @@ begin if v_done_active = '1' and v_batch_done then v_acc := (others => '0'); -- Reset for next batch + accumulator <= (others => '0'); pulse_count <= (others => '0'); else accumulator <= v_acc; diff --git a/mc/Advanced/BoxcarAveragerFullRate/vhdl/Top.vhd b/mc/Advanced/BoxcarAveragerFullRate/vhdl/Top.vhd index edf4809..ebc7635 100644 --- a/mc/Advanced/BoxcarAveragerFullRate/vhdl/Top.vhd +++ b/mc/Advanced/BoxcarAveragerFullRate/vhdl/Top.vhd @@ -101,12 +101,11 @@ begin if Control(5)(1) = '0' then for k in 0 to G_NUM_SAMPLES - 1 loop - -- Use delayed window to align with gain_out + OutputB(k) <= (others => '0'); if boxcar_window(k) = '1' then + -- Use delayed window to align with gain_out -- if boxcar_window_d(C_WINDOW_DELAY - 1)(k) = '1' then OutputB(k)(10) <= '1'; - else - OutputB(k)(10) <= '0'; end if; end loop; else