我正在寻找一种快速的方法来对 81 个数字进行部分排序 - 理想情况下,我希望提取最低的 16 个值(16 个值没有必要以绝对正确的顺序排列)。
目标是 FPGA 中的专用硬件 - 所以这有点复杂,因为我希望最终实现的区域尽可能小。我查看并实现了奇偶合并排序算法,但理想情况下,我正在寻找任何可能对我的需求更有效的东西(交易算法实现大小以获得最低 16 的部分排序,不一定按顺序而不是全排序)
任何建议都会非常受欢迎
非常感谢
这可以及时完成O(nlog_k)
,在您的情况下,n = 81 和 k = 16。当您处理大量元素时,这比O(nlog_n)
.
算法如下:
n
与堆中的最大值进行比较(如果大于最大值则跳过,如果小于最大值,则删除max
并添加n
。)这样,在每次迭代中,您都可以从当前处理的列表部分中跟踪最小的 k 数。
这听起来像是某种信号处理内核。如果不知道设计中的确切数据流,很难帮助回答这个问题。任何涉及排序的算法都有地址解码成本,因为您需要能够写入和读取 81 个元素的内存。如果此数据在内存中,则该成本已经支付,但如果它在不同的寄存器中,则写入它们会产生区域成本。
假设数据在内存中,您可以使用冒泡排序并取底部 16 个值。下面的代码假设有一个双端口存储器,但它可以通过在每个时钟周期交替读取和写入使用一个临时寄存器来存储写入值和写入索引来与单个端口一起工作。如果内存中只有 81 个元素,这可能不会更节省面积。或者,源存储器可以实现为两个单端口存储器,其中一个具有奇数索引,另一个具有偶数索引。
// Not working code
reg [15:0] inData [80:0]; // Must be two-port
reg [3:0] iterCount = 0;
reg [6:0] index = 0;
reg sorting;
always @(posedge clk)
begin
// Some condition to control execution
if(sorting)
begin
if(index == 80)
begin
// Stop after 16 iterations
if(iterCount == 15)
begin
sorting <= 0;
iterCount <= 0;
end
else
begin
iterCount <= iterCount+1;
index <= 0;
end
end
else
begin
// If this is smaller than next item
if(inData[index] < inData[index+1])
begin
// Swap with next item
inData[index+1] <= inData[index];
inData[index] <= inData[index+1];
end
index <= index + 1;
end
end
end
编辑:如果您受到延迟限制,只允许一个时钟域并且必须流水线,那么问题仅限于选择排序网络并将其映射到流水线。您不能使用资源共享,因此根据您的分拣网络,区域是固定的。
也许修改的中位数选择是一种选择?否则,只求最少 16 次是否可行?
首先设置一个包含 16 个值的数组。并使用选择排序之类的东西: