此峰值检测代码有什么问题?我希望每个峰值都有一个触发器。该块的输入是包络形式信号。
module Peak(
input clk,
input m_axis_tready,
input s_axis_tvalid,
input signed [15:0] s_axis_tdata,
output reg trigger
);
reg signed [15:0] prev_s_axis_tdata;
reg signed [15:0] derivative;
reg peak_detected;
parameter signed [15:0] threshold = 1000;
always @(posedge clk ) begin
if (m_axis_tready && s_axis_tvalid) begin
// Compute the derivative of the envelope
derivative <= s_axis_tdata - prev_s_axis_tdata;
// Detect peak using the first derivative method and threshold
if (derivative < 0 && s_axis_tdata > (prev_s_axis_tdata + threshold)) begin
trigger <= 1; // Rising edge indicates a peak in the envelope
peak_detected <= 1;
end else begin
trigger <= 0;
peak_detected <= 0;
end
// Update previous envelope
prev_s_axis_tdata <= s_axis_tdata;
end
end
endmodule
稍微修改了逻辑,将决策逻辑移至组合过程,以便在与当前样本的实际峰值相同的时钟中断言峰值。
RTL
module Peak(
input clk,
input m_axis_tready,
input s_axis_tvalid,
input signed [15:0] s_axis_tdata,
output reg trigger
);
reg signed [15:0] prev_s_axis_tdata;
reg signed [15:0] derivative;
reg peak_detected;
parameter signed [15:0] threshold = 1000;
always @(posedge clk ) begin :ready_valid_block
if (m_axis_tready && s_axis_tvalid) begin
// Compute the derivative of the envelope
derivative <= s_axis_tdata - prev_s_axis_tdata;
end
// Update previous envelope
prev_s_axis_tdata <= s_axis_tdata;
end :ready_valid_block
always_comb
// Detect peak using the first derivative method and threshold
if ( (derivative < 0) &&
(s_axis_tdata > (prev_s_axis_tdata ) &&
(s_axis_tdata >= threshold)) )
begin
trigger <= 1; // Rising edge indicates a peak in the envelope
peak_detected <= 1;
end
else begin
trigger <= 0;
peak_detected <= 0;
end
endmodule
测试台
module tb ();
bit clk;
logic m_axis_tready;
logic s_axis_tvalid;
logic signed [15:0] s_axis_tdata;
logic trigger;
always #5 clk = !clk;
initial begin
$dumpfile("dump.vcd"); $dumpvars;
m_axis_tready <= 1;
s_axis_tvalid <= 1;
s_axis_tdata <= 0;
repeat(2) @(posedge clk);
s_axis_tdata <= 1;
@(posedge clk);
s_axis_tdata <= 2;
@(posedge clk);
s_axis_tdata <= 3;
@(posedge clk);
s_axis_tdata <= 1;
@(posedge clk);
s_axis_tdata <= 1001;
@(posedge clk);
s_axis_tdata <= 1000;
@(posedge clk);
s_axis_tdata <= 999 ;
@(posedge clk);
s_axis_tdata <= 998;
$finish;
end
Peak dut (.*) ;
initial
$monitor("s_axis_tdata = %00d, deriv = %0d, peak_detected = %0d, trigger = %b",
dut.s_axis_tdata,dut.derivative,dut.peak_detected,dut.trigger);
endmodule
输出
s_axis_tdata = 0, deriv = x, peak_detected = 0, trigger = 0
s_axis_tdata = 1, deriv = 0, peak_detected = 0, trigger = 0
s_axis_tdata = 2, deriv = 1, peak_detected = 0, trigger = 0
s_axis_tdata = 3, deriv = 1, peak_detected = 0, trigger = 0
s_axis_tdata = 1, deriv = 1, peak_detected = 0, trigger = 0
s_axis_tdata = 1001, deriv = -2, peak_detected = 1, trigger = 1
s_axis_tdata = 1000, deriv = 1000, peak_detected = 0, trigger = 0
s_axis_tdata = 999, deriv = -1, peak_detected = 0, trigger = 0