前言
2023.5.7 最近在做其他项目内容
一、数据包检测器
正常情况下数据包由起始码(16bit)、数据段(n byte<256)、结束码(16bit)3部分组成。起始码为0xFF00
,结束码为0xFF01
。在一个完整的数据包中,数据段部分不会出现起始码和结束码,请设计一个电路在码流中检测完整且有效的数据包,并输出当前数据包的有效数据长度n。
module data_packet_detect(
input clk,
input rstn,
input [7:0] din,
input din_vld, //输入数据有效信号
output [7:0] data_cnt, //数据包的有效长度,类型是wire
output data_cnt_vld
);
localparam IDLE = 0;
localparam START = 1;
localparam DATA = 2;
localparam OVER = 3;
reg [1:0] state,next_state;
reg [7:0] data_cnt_reg; //所以这里定义一个reg来储存长度
reg flag_FF; // 此标志位为数据包将结束时收到的FF
always @(posedge clk or negedge rstn) begin
if(!rstn) state <= IDLE;
else state <= next_state;
end
always @(*) begin
case(state)
IDLE:
begin
if(din_vld && din == 8'hFF) next_state = START;
else next_state = IDLE;
end
START:
begin
if(din_vld && din == 8'h00) next_state = DATA;
else next_state = IDLE;
end
DATA:
begin
if(din_vld && din == 8'h01 && flag_FF) next_state = OVER; //收到FF01
else next_state = DATA;
end
OVER:
begin
next_state = IDLE;
end
default: next_state = IDLE;
endcase
end
always @(posedge clk or negedge rstn) begin
if(!rstn) data_cnt_reg <= 8'd0;
else begin
if(state == DATA) data_cnt_reg <= data_cnt_reg + 1'b1;
else if(state == OVER) data_cnt_reg <= 8'd0;
else data_cnt_reg <= data_cnt_reg;
end
end
always @(posedge clk or negedge rstn) begin
if(!rstn) flag_FF <= 1'b0;
else begin
if(din_vld && state == DATA && din == 8'hFF) flag_FF <= 1'b1;
else flag_FF <= 1'b0;
end
end
assign data_cnt_vld = (state == OVER)? 1'b1 : 1'b0;
assign data_cnt = data_cnt_reg - 2'd2; // 实际数据包长度需要减去结束标志位的2个字节
endmodule