基于verilog实现数据检测-基于状态机的数据检测

  对于发送端发送送来的数据流,我们需要检测出其帧头来判断一帧的开始,从而开始接收数据。

  本人采用了接收1011010码流的例子来讲解如何实现数据流的检测。

  首先,先画好接收码流的状态图:

这里做下简单的解释:当前数据为0时,一直等待1的到来,1到后跳转S1状态(已检测数据1),在等待0的到来,如果数据为1到则返回IDLE(图上写错了)从新开始检测;此时接收了10了,状态跳转S2(已检测数据10),继续检测数据1,如果到达的数据为0则返回IDLE,为1则进入S3状态(已检测数据101),到S3状态时如果接受数据为1直接进入S4,需要注意的是,当数据为0时,此时已检测的数据为1010,状态可跳至S2,相当于把前面的10舍去了重新检测S3,S4。在S4(已检测数据1011),按照上面的方法可完成检测

verilog代码如下:

module check_data(
    input clk,
    input rst_n,
    input data_in,
    output reg data_flag1,
    output reg[3:0] nxt_state,
    output reg data_receive
);

reg[3:0] cur_state;
//check data 1011010
//always @(posedge clk or negedge rst_n) begin
//    if(!rst_n) begin
//        cur_state <= 0;
//        data_receive <= 0;
//        data_flag1 <= 0;
//        nxt_state <= 0;
//    end
//    else
//        cur_state <= nxt_state;
//end

always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
    data_receive <= 0;
    data_flag1 <= 0;
    nxt_state <= 0;
  end
  else begin
    case(nxt_state)
        4'd0: begin
                  data_receive <= 1'b0;
                  data_flag1 <= 1'b0;
                  if(data_in)
                    nxt_state <= 4'd1;
                else
                    nxt_state <= 4'd0;
               end
        4'd1:    if(!data_in)
                    nxt_state <= 4'd2;
                else
                    nxt_state <= 4'd0;
        4'd2:    if(data_in)
                    nxt_state <= 4'd3;
                else
                    nxt_state <= 4'd0;
        4'd3:    if(data_in)
                    nxt_state <= 4'd4;
                else begin
                    data_flag1 <= 1;
                    nxt_state <= 4'd2;
                end
        4'd4:    if(!data_in)
                    nxt_state <= 4'd5;
                else
                    nxt_state <= 4'd1;
        4'd5:    if(data_in)
                    nxt_state <= 4'd6;
                else
                    nxt_state <= 4'd0;
        4'd6:    if(!data_in) begin
                    nxt_state <= 4'd0;
                    data_receive <= 1'b1;
                end
                else
                    nxt_state <= 4'd4;
        default: nxt_state <= 4'd0;
    endcase
    end
end



endmodule

仿真tb:

module top_tb();

reg clk;
reg rst_n;
reg data_in;
wire data_receive;

initial begin
    clk = 1;
    rst_n = 0;
    data_in = 0;
    
    forever begin
    #20 clk = ~clk;
    end
end

initial begin
    forever begin
       #40 data_in = $random;
    end
 end

initial begin 
    #2000 rst_n = 1;
 end

check_data tb(
    .clk(clk),
    .rst_n(rst_n),
    .data_in(data_in),
    .data_receive(data_receive)
);
endmodule

仿真波形:

2020.12.31更新

添加了s4状态处的探测信号,看看检测数据流1011010中检测到101时检测1/0状态跳变情况,在上面已经说过了如果检测出0.则为1010  可将状态跳回去仿真数据流漏检。  

原文地址:https://www.cnblogs.com/johor-yangmumu/p/14208516.html