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

本人采用了接收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代码如下:

modulecheck_data(inputclk,inputrst_n,inputdata_in,output regdata_flag1,output reg[3:0] nxt_state,output regdata_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) begindata_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;

elsenxt_state<= 4'd0;

end

4'd1: if(!data_in)

nxt_state <= 4'd2;

elsenxt_state<= 4'd0;

4'd2: if(data_in)

nxt_state <= 4'd3;

elsenxt_state<= 4'd0;

4'd3: if(data_in)

nxt_state <= 4'd4;

else begindata_flag1<= 1;

nxt_state<= 4'd2;

end

4'd4: if(!data_in)

nxt_state <= 4'd5;

elsenxt_state<= 4'd1;

4'd5: if(data_in)

nxt_state <= 4'd6;

elsenxt_state<= 4'd0;

4'd6: if(!data_in) begin

nxt_state <= 4'd0;

data_receive <= 1'b1;

end

elsenxt_state<= 4'd4;

default: nxt_state <= 4'd0;

endcase

end

end

endmodule

仿真tb:

moduletop_tb();regclk;regrst_n;regdata_in;wiredata_receive;initial beginclk= 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;endcheck_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  可将状态跳回去仿真数据流漏检。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐