基於verilog實現資料檢測
阿新 • • 發佈:2020-12-29
對於傳送端傳送送來的資料流,我們需要檢測出其幀頭來判斷一幀的開始,從而開始接收資料。
本人採用了接收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; endelse 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; end4'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
模擬波形: