当前位置:   article > 正文

数字IC面试手撕代码(四)_海思面试手撕代码

海思面试手撕代码

在某个群看到某个大佬,面试海康数字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


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103

这个代码仿真过了,功能基本没什么问题。在这里插入图片描述
就是值的注意的是,在通过flag计数的时候,最后的结果减1才是真正的有效数据结果。因为如上图中16’h000f和16’h87ff其实是无效的的,因为有效的数据段是在这两组数据的中间,所以应该减去2。但是为什么只会减去1呢?这是因为如下图在这里插入图片描述
有什么问题,请指出来,大家一块讨论。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/425178
推荐阅读
相关标签
  

闽ICP备14008679号