zoukankan      html  css  js  c++  java
  • 由序列检测启发:数据流滑动窗口操作

      通信中我们常用序列检测器用来检测通信帧的同步帧头,以此达到同步的目的。序列检测就是对于不断输入的二进制数据流中检测出特定序列的二进制数据流。

    比如在10101100100101中检测110010。这种一般采用移位寄存器来实现,可以自行百度:移位寄存器实现序列检测。

      关键字:滑动窗口法;verilog;FPGA;均值滤波

      然而这篇博文想传播的思想是:我们能不能直接移位检测采样后的数据流呢?  比如采样8bit din:8‘d55,8'd111,8'd40,8'd122,8'd100,8'd30,8'd120,我们想检测出8'd111,8'd40,8'd122,8'd100。

    这样做能对数据进行均值滤波,这种思想还可以用来做扩频接收中的匹配滤波捕获,本文就拿均值滤波来举例吧。

      假设我们要在采样到的数据流进行均值滤波,数据流输入为12bit,一帧有65个数据,窗口大小为5,对输入数据采用1/4均值。

    代码如下:

    module data_capture
    (
        input clk,rstn,
        
        input in_vld,
        input[11:0] din,
        
        output reg out_vld,
        output reg[31:0] dout
    );
    parameter AVE_DATA_NUM = 3'd5;
    /////////////////////Shift register///////////////////////////
    reg [11:0] data_reg [AVE_DATA_NUM-1:0];
    reg [3:0]temp_i;
    
    always @ (posedge clk)
    begin
        if(rstn || !in_vld)
            for (temp_i=0; temp_i<AVE_DATA_NUM; temp_i=temp_i+1)
                data_reg[temp_i] <= 'd0;
        else
        begin
            data_reg[0] <= din;
            for (temp_i=0; temp_i<AVE_DATA_NUM-1; temp_i=temp_i+1)
                data_reg[temp_i+1] <= data_reg[temp_i];
        end
    end
    
    /////////////////////sum//////////////////////////////
    reg [31:0] sum;
    
    always @ (posedge clk )
    begin
        if (rstn || !in_vld)
            sum <= 'd0;
        else
            sum <= sum + din - data_reg[AVE_DATA_NUM-1]; //Replace the oldest data with the latest input data
    end
    
    ////////////////////cnt////////////////////////////
    reg[8:0] cnt;
    
    always @(posedge clk)
    begin
        if (rstn || !in_vld)
            cnt <= 'd0;
        else if(cnt == 9'd64)
            cnt <= 0;
        else
            cnt <= cnt + 1'b1;
            
    end
    
    ///////////////////dout////////////////////////////
    always @(posedge clk)
    begin
        if (rstn || !in_vld) begin
            dout <= 11'd0;
            out_vld <= 1'd0;
        end
        else if(cnt > 9'd4) begin
            out_vld <= 1'b1;
            dout <= sum>>2; //sum/4。
        end
        else begin
            out_vld <= 1'b0;
            dout    <= 0;
        end
    end    
    
    
    endmodule

    一帧64个12bit,因为窗口大小为5,只有当第5个数据到来时才开始取均值,同时拉高out_vld。

    testbeach如下:

    `timescale 1ns/1ns
    
    module capture_tb();
    
    reg clk,rstn;
    reg in_vld;
    reg[11:0] din;
    
    wire out_vld;
    wire[31:0] dout;
    
    
    initial begin
        clk = 1;
        rstn = 1;
        in_vld = 0;
        #200
            rstn = 0;
            in_vld = 1;
        #10000
        $stop();
    end
    
    always #10 clk = ~clk;
    
    always #20 din = {$random}%100;
    
    data_capture tb(
        .clk(clk),.rstn(rstn),
        
        .in_vld(in_vld),
        .din(din),
        
        .out_vld(out_vld),
        .dout(dout)
    );
    
    endmodule

    仿真图如下所示:

    第一个dout为in_vld拉高之后的29,18,97,29,12的1/4均值;

    第二个dout为in_vld拉高后第二个clk开始采样得到的数据18,97,29,12,89的均值,新来的89把最老的29给顶走了。

    其实计算有些是有小数的,但是FPGA就这样,小数都想下取整了。

  • 相关阅读:
    while循环&CPU占用率高问题深入分析与解决方案
    Jmeter 发送json
    HTTP请求各参数详解
    Fast Stone截图工具使用教程
    程序员必备神器(FastStoneCapture)
    千古第一败家子杨广(打击异己、毫无承担、无识人之明)
    在路上看和今天要解决的问题可能相关的书,顺便工作上实践一下,立码就记住了
    与Qt的联系方式:邮件,论坛,销售,Bug报告
    Qt for Automation
    Qt for WebAssembly
  • 原文地址:https://www.cnblogs.com/johor-yangmumu/p/15195199.html
Copyright © 2011-2022 走看看