如何在包络信号首尾最大点生成触发?代码触发异常排查
仅在包络信号首末峰值生成触发的Verilog实现方案
原代码的核心问题在于peak_detected的重置逻辑仅依赖包络低于阈值,导致:
- 若中间峰值出现前包络短暂跌破阈值,
peak_detected会被重置,从而误触发中间峰值; - 最后一个峰值出现时,若包络未跌破阈值,
peak_detected仍处于已触发状态,导致合法峰值无法被检测。
以下是修改后的实现代码,通过双阶段检测逻辑实现仅触发首末峰值:
`timescale 1ns / 1ps module peak ( input clk, input signed [15:0] envelope, output reg trigger ); reg signed [15:0] prev_envelope; reg signed [15:0] derivative; // 新增状态变量,用于分阶段跟踪峰值 reg first_peak_detected = 0; reg signed [15:0] last_peak_max = 0; reg last_peak_valid = 0; parameter signed [15:0] threshold = 3000; always @(posedge clk) begin derivative <= envelope - prev_envelope; trigger <= 0; // 默认输出0,避免组合逻辑毛刺 // 第一阶段:检测第一个有效峰值 if (!first_peak_detected) begin // 仅在包络从高于阈值的状态下由升转降时触发 if (derivative < 0 && envelope > threshold && prev_envelope > threshold) begin trigger <= 1; first_peak_detected <= 1; // 初始化最后峰值跟踪的基准值 last_peak_max <= envelope; last_peak_valid <= 1; end end // 第二阶段:跟踪后续峰值,直到包络跌破阈值时触发最后一个峰值 else begin // 检测到新的有效峰值(高于阈值的升转降拐点) if (derivative < 0 && envelope > threshold && prev_envelope > threshold) begin // 更新记录的最大峰值 if (envelope > last_peak_max) begin last_peak_max <= envelope; last_peak_valid <= 1; end end // 包络跌破阈值,触发记录的最后一个峰值,并重置状态 if (envelope < threshold && last_peak_valid) begin trigger <= 1; first_peak_detected <= 0; last_peak_max <= 0; last_peak_valid <= 0; end end prev_envelope <= envelope; end endmodule
关键修改说明
- 分阶段检测:第一阶段仅捕获第一个有效峰值,触发后进入第二阶段;第二阶段持续跟踪所有后续峰值的最大值,直到包络跌破阈值时触发最后一个峰值。
- 优化触发条件:增加
prev_envelope > threshold判断,避免包络从低于阈值区间上升到阈值附近时的误触发。 - 消除毛刺:默认将
trigger置0,避免组合逻辑带来的输出抖动问题。
内容的提问来源于stack exchange,提问作者Parsa
相关产品推荐
相关产品推荐

