Verilog プログラミング - 最大値と 2 番目に大きい値のスクリーニング



序章

今年の海康の模擬筆記試験の問題の中には、入力データの最大値と2番目の最大値をスクリーニングするというプログラミングの問題があります。ここにタイムリーなメモを作成してください。

トピックの説明

データ シーケンスをシリアルに入力し、このシーケンスの 1 回の走査のみが実行されるときに最大 2 つの数値を出力する必要があります。次のコードを改善します。

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

問題解決

このトピックを手に入れたばかりで、最大値を取得する方法だけを考えていましたが、逐次走査後の 2 番目の最大値を取得するにはどうすればよいでしょうか?

まず最大値を求める方法を考えます。これは簡単です。データが入力されるたびに、入力データと現在の最大値の関係を比較します。入力データが現在の最大値より大きい場合、次のクロックサイクルは入力データを使用して最大値を更新します。

2 番目に大きい値は、実際には次の値に含めるだけで済みます。

1. 最大値を更新する条件が満たされた場合、現在の最大値が次に大きい値として与えられます。

2. 入力データが現在の 2 番目に大きい値より大きく、現在の最大値以下の場合、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