数字IC手撕代码(五)

之前在群里看到别人说这样一个题目:在一串8bit数据流中,求去掉最大数据和最小数据的和。

module add_data(
	input clk,
	input rst_n,
	input [7:0] din,
	input din_vld,
	output reg [7:0] max_data,
	output reg [7:0] min_data,
	output reg [15:0] sum_data
);

reg [7:0] temp_data_max;
reg [7:0] temp_data_min;
//求最大的数据
always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		temp_data_max <= 8'd0;
	end
	else if((temp_data_max <= din) && din_vld) begin
		temp_data_max <= din;
	end
end
//这一块代码最大问题是,最小值将会始终是复位状态下的0.
/* always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		temp_data_min <= 8'd0;
	end
	else if((temp_data_min >= din) && din_vld) begin
		temp_data_min <= din;
	end
end */

/*
针对这个问题,我想到的解决方法是:利用计数器,将第一个有效数据
在计数器中保存
或者是利用上升沿保存第一个数据,将其作为比较的起始数据
*/
reg din_vld1;
wire neg_din_vld;
wire pos_din_vld;

assign pos_din_vld = din_vld & (~din_vld1);

// reg [7:0] temp_data_start;
// always @ (posedge clk or negedge rst_n) begin
	// if(!rst_n) begin
		// temp_data_start <= 8'd0;
	// end
	// else if(pos_din_vld) begin
		// temp_data_start <= din;
	// end
// end

//求最小的数据
 always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		temp_data_min <= 8'd0;
	end
	else if(pos_din_vld) begin
		temp_data_min <= din;
	end
	else if((temp_data_min >= din) && din_vld) begin
		temp_data_min <= din;
	end
end


//neg din_vld
always @(posedge clk ) begin
	din_vld1 <= din_vld;
end
assign neg_din_vld = din_vld1 & (~din_vld);

always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		max_data <= 8'd0;
		min_data <= 8'd0;
	end
	else if(neg_din_vld) begin
		max_data <= temp_data_max;
		min_data <= temp_data_min;
	end
end

reg [15:0] temp_data_sum;
always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		temp_data_sum <= 16'd0;
	end
	else if(din_vld) begin
		temp_data_sum <= temp_data_sum + din;
	end
end

always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		sum_data <= 16'd0;
	end
	else if(neg_din_vld) begin
		sum_data <= temp_data_sum - temp_data_max - temp_data_min;
	end
end
endmodule


测试代码

`timescale 1ps/1ps
module tb();
reg clk;
reg rst_n;
reg [7:0] din;
reg din_vld;

wire [7:0] max_data;
wire [7:0] min_data;
wire [15:0] sum_add;

add_data u1(
			.clk(clk),
			.rst_n(rst_n),
			.din(din),
			.din_vld(din_vld),
			.max_data(max_data),
			.min_data(min_data),
			.sum_data(sum_data)
);

initial begin
	rst_n = 0;
	clk = 0;
	#13;
	rst_n = 1;
end
always #5 clk = ~clk;

initial begin
	din_vld = 0;
	din = 8'h00;
	@(posedge clk);
	@(posedge clk);
	din_vld = 1;
	din = 8'h83;
	@(posedge clk);
	din = 8'h23;
	@(posedge clk);
	din = 8'h22;
	@(posedge clk);
	din = 8'h12;
	@(posedge clk);
	din = 8'hff;
	@(posedge clk);
	din = 8'h22;
	@(posedge clk);
	din = 8'h11;
	@(posedge clk);
	din = 8'haa;
	@(posedge clk);
	din = 8'h42;
	din_vld = 0;
end

endmodule

在这里插入图片描述
我觉得这个其中有一个点比较坑的就是关于在求最小值的时候,具体关于如何解决,在代码中已经注释过了,如果有更好的想法,可以交流下

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值