【问题标题】:Sorting in verilog with one cycle用一个循环在verilog中排序
【发布时间】:2018-09-06 16:47:14
【问题描述】:

我试图在 verilog 中对 9 个随机数进行排序。我使用冒泡排序(嵌套循环)算法,但我有一个挑战。我想在一个 clk 周期内对它们进行排序,但它不符合我的要求。至少需要 9 个周期才能对它们进行排序。

always @(posedge clk)
begin

if(m >= 68 && sort_valid == 0) begin
    pool_sort[0] <= pool_buffer[66];
    pool_sort[1] <= pool_buffer[65];
    pool_sort[2] <= pool_buffer[64];
    pool_sort[3] <= pool_buffer[34];
    pool_sort[4] <= pool_buffer[33];
    pool_sort[5] <= pool_buffer[32];
    pool_sort[6] <= pool_buffer[2];
    pool_sort[7] <= pool_buffer[1];
    pool_sort[8] <= pool_buffer[0];

sort_valid <= 1;

 end

if(sort_valid == 1) begin
        for(k=0;k<8;k=k+1) begin
            if(pool_sort[k] < pool_sort[k+1]) begin
                pool_sort[k] <= pool_sort[k+1];
                pool_sort[k+1] <= pool_sort[k];
            end
        end
    if(sort_counter == 0) begin
        sort_valid <= 0;
        pool_out <= pool_sort[0];
    end
end
end

always @(posedge clk)
begin

if(sort_valid == 1) begin
sort_counter <= sort_counter - 1;
end
if(sort_counter == 0) begin
    sort_counter <= 8;
end

end
endmodule

这是我目前为止的排序算法。

【问题讨论】:

标签: sorting verilog


【解决方案1】:

这是一个用于 Verilog 的可参数化的 1 时钟周期分类器(灵感来自 here,但我对模块进行了参数化,减少了周期数,并进行了一些清理)。

它会在模拟中做你想做的事,但是当你合成它时它可能会很大很丑。

module sort #(
    parameter NUM_VALS = 5,
    parameter SIZE     = 16
)(  input  wire clk,
    input  wire [NUM_VALS*SIZE-1:0] in,
    output reg  [NUM_VALS*SIZE-1:0] out
);
    reg [NUM_VALS*SIZE-1:0] sorted_bus;
    always @(posedge clk) begin
        out <= sorted_bus;
    end

    integer i, j;
    reg [SIZE-1:0] temp;
    reg [SIZE-1:0] array [1:NUM_VALS];
    always @* begin
        for (i = 0; i < NUM_VALS; i = i + 1) begin
            array[i+1] = in[i*SIZE +: SIZE];
        end

        for (i = NUM_VALS; i > 0; i = i - 1) begin
            for (j = 1 ; j < i; j = j + 1) begin
                if (array[j] < array[j + 1]) begin
                    temp         = array[j];
                    array[j]     = array[j + 1];
                    array[j + 1] = temp;
                end 
            end
        end

       for (i = 0; i < NUM_VALS; i = i + 1) begin
            sorted_bus[i*SIZE +: SIZE] = array[i+1];
       end
    end
endmodule

还有一个测试台:

module sort_tb;
    reg clk;
    reg  [16-1:0] in1,  in2,  in3,  in4,  in5;
    wire [16-1:0] out1, out2, out3, out4, out5;

    sort #(.NUM_VALS(5), .SIZE(16)) dut (
        .clk(clk),
        .in ({in1,  in2,  in3,  in4,  in5}),
        .out({out1, out2, out3, out4, out5})
    );

    always @(posedge clk) begin
        in1 <= $random;
        in2 <= $random;
        in3 <= $random;
        in4 <= $random;
        in5 <= $random;
    end

    always @(posedge clk) begin
        $display("In:  %0d %0d %0d %0d %0d", in1,  in2,  in3,  in4,  in5);
        $display("Out: %0d %0d %0d %0d %0d", out1, out2, out3, out4, out5);
    end

    initial begin
        #100;
        $finish;
    end

    always begin
        clk = 1'b0; #5;
        clk = 1'b1; #5;
    end
endmodule

【讨论】:

    【解决方案2】:

    如果您需要对多轮 9 个数字进行排序,请提前考虑。

    您可以在 1 个周期内进行排序,但最高频率可能会受到很大限制。但是,如果您在低频下花费 1 个时钟周期,或者在更高频率下花费 9 个时钟,这并不重要。

    如果您有很多轮次,那么您可以流水线排序阶段,在每个时钟周期获得新结果,第一个结果有一些时钟延迟。

    另请参阅https://en.wikipedia.org/wiki/Bitonic_sorter,因为它更适用于输入数量较少的硬件中的并行排序。

    【讨论】:

    • 我不认为双调算法可以在一个周期内执行
    • 是什么让你这么认为?您只需将所有比较阶段链接到一个长组合函数中,一旦输入传播到所有阶段,您就会得到结果。这会限制你的频率,但它仍然是 1 个周期。使用流水线(对于许多排序),您可以在一个周期内执行一个阶段,这会给您带来延迟,并在此之后每 1 个时钟产生一个结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多