Verilog 编程——筛选最大值与次大值



引言

海康今年的实习笔试题目中有一道编程题目,就是关于筛选输入数据中的最大值与次大值。在这里做一个及时的记录。

题目描述

串行输入一个数据序列,要求在对这个序列仅进行1次遍历的情况下,输出最大的两个数。完善如下代码:

module top2_sort #(
parameter DWIDTH = 8
)(
input               clk,
input               rst_n,
input               srst,
input [DWIDTH-1:0]  din,
input               din_vld,
output reg [DWIDTH-1:0] dout_top1,
output reg [DWIDTH-1:0] dout_top2,

output reg              doubt_vld
    );

//待完善
//=================================
endmodule

解题

刚拿到这个题目,我只想到的是如何得到最大值,那么次大值如何也在依次遍历结束后得到呢?

先考虑最大值如何得到,这个简单,每次数据输入时,比较输入数据和当前最大值的关系,如果输入数据大于当前最大值,那么下个时钟周期就用输入数据更新最大值。

次大值其实只需要在,

1、更新最大值的条件满足时,将当前最大值给到次大值;

2、在输入数据大于当前次大值但不大于当前最大值时,更新次大值;

按照这个思路可以得到输入序列最大的前N个数。

编程

设计代码:

// ========================================================================
// 功能描述:-1- 找出输入序列的最大值 次大值
// 作者:Xu Y. B.
// 时间:2023-05-08
// ========================================================================


`timescale 1ns / 1ps

module top2_sort #(
parameter DWIDTH = 8
)(
input 							clk,
input 							rst_n,
input 		[DWIDTH-1:0]		din,						
input 							din_vld,						
output reg [DWIDTH-1:0] 		dout_top1,						
output reg [DWIDTH-1:0] 		dout_top2,						
output reg  					doubt_vld	
    );


always @ (posedge clk)
begin
	if(~rst_n)
	begin
		dout_top1 <= 0;
		dout_top2 <= 0;
	end
	else if(din_vld && (din > dout_top1))
	begin
		dout_top1 <= din;
		dout_top2 <= dout_top1;		
	end
	else if(din_vld && (din > dout_top2))
	begin
		dout_top2 <= din;
	end
end

always @ (posedge clk)
begin
	if(~rst_n)
	begin
		doubt_vld <= 1'b0;
	end
	else
	begin
		doubt_vld <= din_vld;
	end
end


endmodule

仿真代码:

// ========================================================================
// 功能描述:-1- 仿真验证模块 top2_sort 的功能
// 作者:Xu Y. B.
// 时间:2023-05-08
// ========================================================================



`timescale 1ns / 1ps

module tb_top2_sort();
parameter 	DWIDTH 		= 		8;

reg 							clk;
reg 							rst_n;
reg 		[DWIDTH-1:0]		din;						
reg 							din_vld;

wire 		[DWIDTH-1:0] 		dout_top1;						
wire 		[DWIDTH-1:0] 		dout_top2;						
wire  							doubt_vld;

initial clk = 1'b0;
always #10 clk = ~clk;

initial
begin
	rst_n   <= 1'b0;
	din     <= 0;
	din_vld	<= 0;
	#103;
	@(posedge clk)
	rst_n   <= 1;
	#103;
	@(posedge clk)
	din     <= 56;
	din_vld	<= 1;	

	@(posedge clk)
	din     <= 12;

	@(posedge clk)
	din     <= 109;

	@(posedge clk)
	din     <= 13;

	@(posedge clk)
	din     <= 1;

	@(posedge clk)
	din     <= 192;

	@(posedge clk)
	din     <= 127;

	@(posedge clk)
	din     <= 101;

	@(posedge clk)
	din     <= 189;

	@(posedge clk)
	din     <= 133;

	@(posedge clk)
	din     <= 145;

	@(posedge clk)
	din     <= 92;

	@(posedge clk)
	din     <= 44;

	@(posedge clk)
	din     <= 56;

	@(posedge clk)	
	din_vld	<= 0;	

	#102;
	$finish;
end

top2_sort #(
		.DWIDTH(DWIDTH)
	) INST_top2_sort (
		.clk       (clk),
		.rst_n     (rst_n),
		.din       (din),
		.din_vld   (din_vld),

		.dout_top1 (dout_top1),
		.dout_top2 (dout_top2),
		.doubt_vld (doubt_vld)
	);

endmodule

仿真结果:



有其他实现思路,希望可以在评论区留言交流~

猜你喜欢

转载自blog.csdn.net/qq_43045275/article/details/130568937