1. 程式人生 > 實用技巧 >基於verilog實現資料檢測

基於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_receive
);

reg[3:0] cur_state;
reg[3:0] nxt_state;
//check data 1011010
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        cur_state <= 0;
        data_receive <= 0;
    end
else cur_state <= nxt_state; end always @(*) begin case(cur_state) 4'd0: begin data_receive <= 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 nxt_state <= 4'd2; 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 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

模擬波形: