我想检测包络形式的峰值,但此代码无法正常工作。有什么问题吗?

问题描述 投票:0回答:1

此峰值检测代码有什么问题?我希望每个峰值都有一个触发器。该块的输入是包络形式信号。

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
verilog system-verilog
1个回答
0
投票

稍微修改了逻辑,将决策逻辑移至组合过程,以便在与当前样本的实际峰值相同的时钟中断言峰值。

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
© www.soinside.com 2019 - 2024. All rights reserved.