题目描述:输入一组数据,剔除最大值、最小值的累加模块
分析:首先定义两个寄存器,分别存储最大值和最小值;定义两个计数器,分别存储最大值、最小值出现的次数;
定义一个寄存器,累加每次输入的数据sum_r;最后将总和减去所有的最大值和最小值即可。
注意:1.很容易忽略最大值、最小值重复出现的情况;
2.min的初始值不能设置为0,而应该设置为最大值,这样才能筛选到最小值;
3一组数据传输完成后,要清零所有寄存器,为下一组数据的到来做准备
上代码:
//description:对输入的数据去除最大值,去除最小值,求和(考虑最大值、最小值重复出现)
module sum_filter(
input clk,
input rst_n,
input data_valid,
input [15:0] data_in,
output reg [31:0] sum,
output reg done
);
reg [15:0]max; //最大数据寄存器
reg [15:0]min; //最小数据寄存器
reg [15:0]max_cnt; //最大的数出现的次数
reg [15:0]min_cnt; //最小的数出现的次数
reg [31:0]sum_r; //所有输入数据的和
reg valid_r; //valid打一拍
wire nege; //valid下降沿
//计数最大值以及出现的次数
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
max<=16'd0;
max_cnt<=16'd0;
end
else if(data_valid)
begin
if(data_in>max)
begin
max<=data_in;
max_cnt<=16'd1;
end
else if(data_in==max)
begin
max<=max;
max_cnt<=max_cnt+16'd1;
end
else
begin
max<=max;
max_cnt<=max_cnt;
end
end
else //数据传输完成后清0
begin
max<=16'd0;
max_cnt<=16'd0;
end
//计数最小值以及出现的次数
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
min<=16'hffff; //初始值设为最大,这样才能检测到最小值
min_cnt<=16'd0;
end
else if(data_valid)
begin
if(data_in==min)
begin
min<=min;
min_cnt<=min_cnt+16'd1;
end
else if(data_in<min)
begin
min<=data_in;
min_cnt<=16'd1;
end
else
begin
min<=min;
min_cnt<=min_cnt;
end
end
else //数据传输完成后重新置位
begin
min<=16'hffff;
min_cnt<=16'd0;
end
//累加
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
sum_r<=32'd0;
end
else if(data_valid)
begin
sum_r<=sum_r+data_in;
end
else //数据传输完成后清0
begin
sum_r<=32'd0;
end
//valid下降沿
always@(posedge clk)
valid_r<=data_valid;
assign nege=~data_valid&valid_r;
//完成信号
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
done<=1'b0;
end
else if(nege) //数据传输结束,产生完成信号
begin
done<=1'b1;
end
else
begin
done<=1'b0;
end
//减去最大值、最小值
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
sum<=32'd0;
end
else if(nege) //当数据传输结束时,减去左右最大值和最小值
begin
sum<=sum_r-max*max_cnt-min*min_cnt;
end
else
begin
sum<=sum;
end
endmodule
再给出一个错误实例:
module sum_filter_v0(
input clk,
input rst_n,
input data_valid,
input [15:0] data_in,
output reg [31:0] sum,
output reg done
);
reg [15:0]max; //最大数据寄存器
reg [15:0]min; //最小数据寄存器
reg [31:0]sum_r; //所有输入数据的和
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
max<=16'd0;
min<=16'hffff;
sum_r<=32'd0;
end
else if(data_valid)
begin
if(data_in>max)
begin
max<=data_in;
sum_r<=sum_r+max;
min<=min;
end
else if(data_in<min)
begin
min<=data_in;
sum_r<=sum_r+min;
max<=max;
end
else
begin
min<=min;
max<=max;
sum_r<=sum_r+data_in;
end
end
endmodule
上述代码,首先不能检测出重复最大值、最小值的情况;其次不能很好地检测到最小值:如数据流为1,2,3,4,5,6,7,8,这样就只能剔除最大值,而不能剔除最小值。所以最大值、最小值的检测应该分开