zoukankan      html  css  js  c++  java
  • 基于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  可将状态跳回去仿真数据流漏检。  

  • 相关阅读:
    【UGUI】源码 -- 0总框架
    【Unity】 细说AssetBundle
    Unity文件引用、meta文件详解
    ( 资源管理器03 )Prefab加载自动化管理引用计数管理器
    ( 资源管理器 02 )AssetBundle 同步异步引用计数资源加载管理器
    ( 资源管理器 01 )Asset同步异步引用计数资源加载管理器
    git status 显示中文和解决中文乱码
    C# 16进制与字符串、字节数组之间的转换
    mac地址转byte数组
    unity插件调用打印机
  • 原文地址:https://www.cnblogs.com/johor-yangmumu/p/14208516.html
Copyright © 2011-2022 走看看