赞
踩
在某个群看到某个大佬,面试海康数字IC实习的时候让手撕代码。现在也把这个题目复现一下。
题目正常情况下数据包由起始码(16bit)、数据段(n bytes n < 256 )、结束码(16bit)三部分组成。起始码为0xFF00、结束码为0xFF01。在一个完整的数据包中,数据段部分不会出现起始码和结束码。请设计一个电路在码流中检测完整且有效的数据包,并输出当前数据包的有效长度n。输入接口in:clk、rst_n、din[7:0]、din_vld
输出接口out:data_cnt[7:0]、data_cnt_vld。
刚开始看了这个题目,也没有仔细多想,看了那个大佬的描述之后,应该注意:异常检测(结束码还没出现的时候如果超过255bytes的数据要报异常、如果中间出现起始码要报异常)。所以应该在上面的输出端口上加上两个异常标志位。
接下来就是我对这个题目的代码的书写:
module data( input clk, input rst_n, input [7:0] din, input din_vld, output reg [7:0] data_cnt_1, output data_cnt_vld, output error_start, output error_cnt ); reg [15:0] temp_data; reg [7:0] data_cnt; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin temp_data <= 16'd0; end else if(din_vld) begin temp_data <= {temp_data[7:0],din}; end end reg flag; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin flag <= 1'b0; end else if(din_vld) begin if(temp_data==16'hff00) begin flag <= 1'b1; end else if(temp_data==16'hff01) begin flag <= 1'b0; end end end //error_start /* always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin error_start <= 1'b0; end else if(flag && (temp_data==16'hff00)) begin error_start <= 1'b1; end else begin error_start <= 1'b0; end end*/ assign error_start = (flag && (temp_data==16'hff00)) ? 1'b1 : 1'b0; //error_cnt /* always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin error_cnt <= 1'b0; end else if(flag && data_cnt==8'd255 && temp_data!=16'hff01) begin error_cnt <= 1'b1; end else begin error_cnt <= 1'b0; end end */ assign error_cnt = (flag && (data_cnt==8'd254) && temp_data!=16'hff01) ? 1'b1 : 1'b0; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin data_cnt <= 8'd0; end else if(error_start || error_cnt) begin data_cnt <= 8'd0; end else if(flag && temp_data==16'hff01) begin data_cnt <= 8'd0; end else if(flag && din_vld) begin data_cnt <= data_cnt + 1'b1; end end /* always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin data_cnt_vld <= 1'b0; end else if(flag && temp_data==16'hff01) begin data_cnt_vld <= 1'b1; end else begin data_cnt_vld <= 1'b0; end end */ assign data_cnt_vld = (flag && temp_data==16'hff01) ? 1'b1 : 1'b0; always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin data_cnt_1 <= 8'd0; end else if(flag && temp_data==16'hff01)begin data_cnt_1 <= data_cnt-1; end end endmodule
这个代码仿真过了,功能基本没什么问题。
就是值的注意的是,在通过flag计数的时候,最后的结果减1才是真正的有效数据结果。因为如上图中16’h000f和16’h87ff其实是无效的的,因为有效的数据段是在这两组数据的中间,所以应该减去2。但是为什么只会减去1呢?这是因为如下图
有什么问题,请指出来,大家一块讨论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。