序章
今年の海康の模擬筆記試験の問題の中には、入力データの最大値と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
シミュレーション結果:
他に実装のアイデアがある場合は、コメント欄にメッセージを残して交換していただければ幸いです~