之前在群里看到别人说这样一个题目:在一串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
我觉得这个其中有一个点比较坑的就是关于在求最小值的时候,具体关于如何解决,在代码中已经注释过了,如果有更好的想法,可以交流下