基於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  可將狀態跳回去仿真數據流漏檢。  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM