Verilog实现冒泡法排序(可配置数据的数目和位宽)

1冒泡排序

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来

1.1算法步骤

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
Verilog实现冒泡法排序(可配置数据的数目和位宽)_第1张图片

verilog实现

主要的思路是:使用状态机控制冒泡排序的外部循环和内部循环,主要有外部计数器和外部计数器控制,代码里有详细的注释。

`define MAX_SUPPORT 20          // 最大支持输入的数据的数目,可配置
module bubble_sort #(
    parameter   width=8         //输入的每个数据位宽
) (
    input   wire                                clk         ,
    input   wire                                rst_n       ,
    input   wire    [`MAX_SUPPORT*width-1:0]    data        ,       // 输入的所有数据
    input   wire                                valid       ,       // 数据的有效信号(脉冲)
    input   wire    [10:0]                      num         ,       // 数据的数目

    output  wire    [`MAX_SUPPORT*width-1:0]    sort_data   ,
    output  wire                                ready 
);
    localparam      IDLE    =   5'd0    ,       // 空闲态
                    SORT1   =   5'd1    ,       // 第一轮排序
                    SORT2   =   5'd2    ,
                    SORT3   =   5'd3    ,
                    SORT4   =   5'd4    ,
                    SORT5   =   5'd5    ,
                    SORT6   =   5'd6    ,
                    SORT7   =   5'd7    ,
                    SORT8   =   5'd8    ,
                    SORT9   =   5'd9    ,
                    SORT10  =   5'd10    ,
                    SORT11  =   5'd11    ,
                    SORT12   =   5'd12    ,
                    SORT13   =   5'd13    ,
                    SORT14   =   5'd14    ,
                    SORT15   =   5'd15    ,
                    SORT16   =   5'd16    ,
                    SORT17   =   5'd17    ,
                    SORT18   =   5'd18    ,
                    SORT19   =   5'd19    ,
                    SAMPLE   =   5'd20    ;     //空闲态之后的采样态,采样有效数据
    
    reg     [`MAX_SUPPORT*width-1:0]      data_reg    ; //有效数据的寄存

    wire [width-1:0]    data1   =   data_reg[width-1:0]             ;
    wire [width-1:0]    data2   =   data_reg[2*width-1:width]       ;
    wire [width-1:0]    data3   =   data_reg[3*width-1:2*width]     ;
    wire [width-1:0]    data4   =   data_reg[4*width-1:3*width]     ;   
    wire [width-1:0]    data5   =   data_reg[5*width-1:4*width]     ;   
    wire [width-1:0]    data6   =   data_reg[6*width-1:5*width]     ;               
    wire [width-1:0]    data7   =   data_reg[7*width-1:6*width]     ;   
    wire [width-1:0]    data8   =   data_reg[8*width-1:7*width]     ;  
    wire [width-1:0]    data9   =   data_reg[9*width-1:8*width]     ;   
    wire [width-1:0]    data10  =   data_reg[10*width-1:9*width]    ;   
    wire [width-1:0]    data11  =   data_reg[11*width-1:10*width]   ;   
    wire [width-1:0]    data12  =   data_reg[12*width-1:11*width]   ;   
    wire [width-1:0]    data13  =   data_reg[13*width-1:12*width]   ;   
    wire [width-1:0]    data14  =   data_reg[14*width-1:13*width]   ;   
    wire [width-1:0]    data15  =   data_reg[15*width-1:14*width]   ;   
    wire [width-1:0]    data16  =   data_reg[16*width-1:15*width]   ;   
    wire [width-1:0]    data17  =   data_reg[17*width-1:16*width]   ;   
    wire [width-1:0]    data18  =   data_reg[18*width-1:17*width]   ;
    wire [width-1:0]    data19  =   data_reg[19*width-1:18*width]   ;
    wire [width-1:0]    data20  =   data_reg[20*width-1:19*width]   ;

    reg     [4:0]       state       ;   //有限状态机的现态
    reg     [4:0]       nx_state    ;
    reg     [5:0]       cnt         ;   //冒泡排序的内部循环
    reg     [5:0]       cycle_cnt   ;   //冒泡排序的外部循环
    wire                sort1_flag  ;   //外部第一次循环结束信号
    wire                sort2_flag  ;
    wire                sort3_flag  ;
    wire                sort4_flag  ;
    wire                sort5_flag  ;
    wire                sort6_flag  ;
    wire                sort7_flag  ;
    wire                sort8_flag  ;
    wire                sort9_flag  ;
    wire                sort10_flag ;
    wire                sort11_flag ;
    wire                sort12_flag ;
    wire                sort13_flag ;
    wire                sort14_flag ;
    wire                sort15_flag ;
    wire                sort16_flag ;
    wire                sort17_flag ;
    wire                sort18_flag ;
    wire                sort19_flag ;
    wire                finish_flag ;

    

    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            state <= IDLE;
        else
            state <= nx_state;
    end

    always @(*) begin
        nx_state = IDLE;
        case(state)
            IDLE:   nx_state <= valid ? SAMPLE : IDLE;  // 数据有效跳转到采样态
            SAMPLE: nx_state <= SORT1;
            SORT1:  nx_state <= (~finish_flag) ? (sort1_flag ? SORT2 : SORT1) : IDLE;               
            SORT2:  nx_state <= (~finish_flag) ? (sort2_flag ? SORT3 : SORT2) : IDLE;        
            SORT3:  nx_state <= (~finish_flag) ? (sort3_flag ? SORT4 : SORT3) : IDLE;    
            SORT4:  nx_state <= (~finish_flag) ? (sort4_flag ? SORT5 : SORT4) : IDLE;    
            SORT5:  nx_state <= (~finish_flag) ? (sort5_flag ? SORT6 : SORT5) : IDLE;    
            SORT6:  nx_state <= (~finish_flag) ? (sort6_flag ? SORT7 : SORT6) : IDLE;    
            SORT7:  nx_state <= (~finish_flag) ? (sort7_flag ? SORT8 : SORT7) : IDLE;    
            SORT8:  nx_state <= (~finish_flag) ? (sort8_flag ? SORT9 : SORT8) : IDLE;    
            SORT9:  nx_state <= (~finish_flag) ? (sort9_flag ? SORT10 : SORT9) :IDLE ;   
            SORT10:  nx_state <=(~finish_flag) ? ( sort10_flag ? SORT11 : SORT10) : IDLE;
            SORT11:  nx_state <=(~finish_flag) ? ( sort11_flag ? SORT12 : SORT11) : IDLE;
            SORT12:  nx_state <=(~finish_flag) ? ( sort12_flag ? SORT13 : SORT12) : IDLE;
            SORT13:  nx_state <=(~finish_flag) ? ( sort13_flag ? SORT14 : SORT13) : IDLE;
            SORT14:  nx_state <=(~finish_flag) ? ( sort14_flag ? SORT15 : SORT14) : IDLE;
            SORT15:  nx_state <=(~finish_flag) ? ( sort15_flag ? SORT16 : SORT15) : IDLE;
            SORT16:  nx_state <=(~finish_flag) ? ( sort16_flag ? SORT17 : SORT16) : IDLE;
            SORT17:  nx_state <=(~finish_flag) ? ( sort17_flag ? SORT18 : SORT17) : IDLE;
            SORT18:  nx_state <=(~finish_flag) ? ( sort18_flag ? SORT19 : SORT18) : IDLE;
            SORT19:  nx_state <= sort19_flag ? (valid ? SORT1 : IDLE) : SORT19;
            default: nx_state <= IDLE;
        endcase
    end
    //内部循环计数器 外部循环计数器
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            cnt <= 5'd0;
            cycle_cnt <= 5'd0;
        end
        else begin
            case(nx_state)
                IDLE:   begin
                            cnt <= 5'd0;
                            cycle_cnt <= 5'd0;
                        end
                SAMPLE: begin
                            cnt <= 5'd0;
                            cycle_cnt <= 5'd0;
                        end
                SORT1:  begin
                            cnt <= cnt + 1'b1;
                            cycle_cnt <= (state == IDLE ) ? (cycle_cnt + 1'b1) : (cycle_cnt);
                        end
                SORT2:  begin
                            cnt <= (state == SORT1) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT1) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT3:  begin
                            cnt <= (state == SORT2) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT2) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                
                SORT4:  begin
                            cnt <= (state == SORT3) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT3) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT5:  begin
                            cnt <= (state == SORT4) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT4) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT6:  begin
                            cnt <= (state == SORT5) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT5) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT7:  begin
                            cnt <= (state == SORT6) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT6) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT8:  begin
                            cnt <= (state == SORT7) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT7) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT9:  begin
                            cnt <= (state == SORT8) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT8) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT10:  begin
                            cnt <= (state == SORT9) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT9) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT11:  begin
                            cnt <= (state == SORT10) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT10) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT12:  begin
                            cnt <= (state == SORT11) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT11) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT13:  begin
                            cnt <= (state == SORT12) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT12) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT14:  begin
                            cnt <= (state == SORT13) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT13) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT15:  begin
                            cnt <= (state == SORT14) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT14) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT16:  begin
                            cnt <= (state == SORT15) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT15) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT17:  begin
                            cnt <= (state == SORT16) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT16) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT18:  begin
                            cnt <= (state == SORT17) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT17) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                SORT19:  begin
                            cnt <= (state == SORT18) ? 5'd0 : cnt + 1'b1;
                            cycle_cnt <= (state == SORT18) ? (cycle_cnt + 1'b1) : cycle_cnt;
                        end
                default:begin
                            cnt <= 5'd0;
                            cycle_cnt <= 5'd0;
                        end
            endcase
        end
    end

    assign sort1_flag = (state == SORT1) && (cnt == num - 2);
    assign sort2_flag = (num - 3 >= 0) ? ((state == SORT2) && (cnt == num - 3)) : 1'b0;
    assign sort3_flag = (num - 4 >= 0) ? ((state == SORT3) && (cnt == num - 4)) : 1'b0;
    assign sort4_flag = (num - 5 >= 0) ? ((state == SORT4) && (cnt == num - 5)) : 1'b0;
    assign sort5_flag = (num - 6 >= 0) ? ((state == SORT5) && (cnt == num - 6)) : 1'b0;
    assign sort6_flag = (num - 7 >= 0) ? ((state == SORT6) && (cnt == num - 7)) : 1'b0;
    assign sort7_flag = (num - 8 >= 0) ? ((state == SORT7) && (cnt == num - 8)) : 1'b0;
    assign sort8_flag = (num - 9 >= 0) ? ((state == SORT8) && (cnt == num - 9)) : 1'b0;
    assign sort9_flag = (num - 10 >= 0) ? ((state == SORT9) && (cnt == num - 10)) : 1'b0;
    assign sort10_flag =(num - 11 >= 0) ? ((state == SORT10) && (cnt == num - 11)) : 1'b0;
    assign sort11_flag = (num - 12 >= 0) ? ((state == SORT11) && (cnt == num - 12)) : 1'b0;
    assign sort12_flag = (num - 13 >= 0) ? ((state == SORT12) && (cnt == num - 13)) : 1'b0;
    assign sort13_flag = (num - 14 >= 0) ? ((state == SORT13) && (cnt == num - 14)) : 1'b0;
    assign sort14_flag = (num - 15 >= 0) ? ((state == SORT14) && (cnt == num - 15)) : 1'b0;
    assign sort15_flag = (num - 16 >= 0) ? ((state == SORT15) && (cnt == num - 16)) : 1'b0;
    assign sort16_flag = (num - 17 >= 0) ? ((state == SORT16) && (cnt == num - 17)) : 1'b0;
    assign sort17_flag = (num - 18 >= 0) ? ((state == SORT17) && (cnt == num - 18)) : 1'b0;
    assign sort18_flag = (num - 19 >= 0) ? ((state == SORT18) && (cnt == num - 19)) : 1'b0;
    assign sort19_flag = (num - 20 >= 0) ? ((state == SORT19) && (cnt == num - 20)) : 1'b0;

    assign finish_flag = (cycle_cnt == num - 1) && (cnt == 0);
    assign sort_data = data_reg;
    assign ready = finish_flag;

    //swap 数据交换
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin
            data_reg <= 'd0;
        end
        else begin
            case(nx_state)
                IDLE:   data_reg <= 'd0;
                SAMPLE: data_reg <= data;
                SORT1:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT2:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT3:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT4:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT5:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT6:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT7:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT8:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT9:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT10:  begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT11: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT12: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT13: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT14: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT15: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT16: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT17: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT18: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                SORT19: begin  //data_reg[(cnt+1)*width-1:cnt*width] <= data_regend
                            if(data_reg[(cnt+2)*width-1 -: width] < data_reg[(cnt+1)*width-1 -: width])begin
                                data_reg[(cnt+2)*width-1 -: width] <= data_reg[(cnt+1)*width-1 -: width];
                                data_reg[(cnt+1)*width-1 -: width] <= data_reg[(cnt+2)*width-1 -: width];
                            end
                        end
                default:;
            endcase
        end   
    end

endmodule   

Testbench

`timescale  1ns/1ns
`define MAX_SUPPORT 20
`define WIDTH   8
module tb_bubble_sort();

    reg                                 clk         ;
    reg                                 rst_n       ;
    reg     [`MAX_SUPPORT*`WIDTH-1:0]   data        ;
    reg                                 valid       ;
    reg     [10:0]                      num         ;

    wire    [`MAX_SUPPORT*`WIDTH-1:0]   sort_data   ;
    wire                                ready       ;

    wire    [`WIDTH-1:0]                data1       ;
    wire    [`WIDTH-1:0]                data2       ;
    wire    [`WIDTH-1:0]                data3       ;
    wire    [`WIDTH-1:0]                data4       ;
    wire    [`WIDTH-1:0]                data5       ;
    wire    [`WIDTH-1:0]                data6       ;
    wire    [`WIDTH-1:0]                data7       ;
    wire    [`WIDTH-1:0]                data8       ;
    wire    [`WIDTH-1:0]                data9       ;
    wire    [`WIDTH-1:0]                data10      ;
    wire    [`WIDTH-1:0]                data11      ;
    wire    [`WIDTH-1:0]                data12      ;
    wire    [`WIDTH-1:0]                data13      ;
    wire    [`WIDTH-1:0]                data14      ;
    wire    [`WIDTH-1:0]                data15      ;
    wire    [`WIDTH-1:0]                data16      ;
    wire    [`WIDTH-1:0]                data17      ;
    wire    [`WIDTH-1:0]                data18      ;
    wire    [`WIDTH-1:0]                data19      ;
    wire    [`WIDTH-1:0]                data20      ;
    reg     [`MAX_SUPPORT*`WIDTH-1:0]   temp_data   ;

    assign  data1   =   temp_data[`WIDTH-1:0];
    assign  data2   =   temp_data[2*`WIDTH-1:1*`WIDTH];
    assign  data3   =   temp_data[3*`WIDTH-1:2*`WIDTH];
    assign  data4   =   temp_data[4*`WIDTH-1:3*`WIDTH];
    assign  data5   =   temp_data[5*`WIDTH-1:4*`WIDTH];
    assign  data6   =   temp_data[6*`WIDTH-1:5*`WIDTH];
    assign  data7   =   temp_data[7*`WIDTH-1:6*`WIDTH];
    assign  data8   =   temp_data[8*`WIDTH-1:7*`WIDTH];
    assign  data9   =   temp_data[9*`WIDTH-1:8*`WIDTH];
    assign  data10   =   temp_data[10*`WIDTH-1:9*`WIDTH];
    assign  data11   =   temp_data[11*`WIDTH-1:10*`WIDTH];
    assign  data12   =   temp_data[12*`WIDTH-1:11*`WIDTH];
    assign  data13   =   temp_data[13*`WIDTH-1:12*`WIDTH];
    assign  data14  =   temp_data[14*`WIDTH-1:13*`WIDTH];
    assign  data15  =   temp_data[15*`WIDTH-1:14*`WIDTH];
    assign  data16  =   temp_data[16*`WIDTH-1:15*`WIDTH];
    assign  data17   =   temp_data[17*`WIDTH-1:16*`WIDTH];
    assign  data18   =   temp_data[18*`WIDTH-1:17*`WIDTH];
    assign  data19   =   temp_data[19*`WIDTH-1:18*`WIDTH];
    assign  data20   =   temp_data[`MAX_SUPPORT*`WIDTH-1:(`MAX_SUPPORT-1)*`WIDTH];
    
    initial begin
        clk = 1'b0;
        rst_n = 1'b0;
        data = {`MAX_SUPPORT*`WIDTH{1'b0}};
        valid = 1'b0;
        temp_data = 'd0;
        num = 'd9;
        #50
        rst_n = 1'b1;
        #20
        repeat(20) begin
            @(posedge clk);
            data_gen();
            valid = 1'b1;
            @ (posedge clk);
            valid = 1'b0;
            @(posedge ready);
        end
        /*
        @(posedge clk);
        data_gen();
        valid = 1'b1;
        @ (posedge clk);
        valid = 1'b0;
        @(posedge ready);
        @(posedge clk);
         data_gen();
         valid = 1'b1;
        @ (posedge clk);
        valid = 1'b0;
        @(posedge ready);
        */
    end
    
    always #10 clk = ~clk;

    task  data_gen;
        begin:www
        integer i;
        for(i = 1; i <= `MAX_SUPPORT; i = i + 1)begin
            if(i <= num)
                temp_data[i*`WIDTH-1 -: `WIDTH] = {$random}%255;
            else
                temp_data[i*`WIDTH-1 -: `WIDTH] = {`WIDTH{1'b0}};
        end
        @(posedge clk);
        data = {data20, data19, data18,data17, data16, data15,data14, data13, data12,
        data11, data10, data9,data8, data7, data6,data5, data4, data3,data2, data1};
        end
    endtask
    bubble_sort #(8) 
u_bubble_sort(
    .clk    (clk)   ,
    .rst_n  (rst_n) ,
    .data   (data)  ,
    .valid  (valid) ,
    .num    (num)   ,

    .sort_data(sort_data),
    .ready  (ready)

);
endmodule

在上面的testbench中num设置为9,则是对9个数据进行冒泡排序,仿真截图如下所示,可知成功进行了排序。
Verilog实现冒泡法排序(可配置数据的数目和位宽)_第2张图片
当然也可以把num设置为其它的数,比如4,仿真截图如下所示:
Verilog实现冒泡法排序(可配置数据的数目和位宽)_第3张图片

总结

这段时间忙着写论文,coding有点懈怠,作为小白继续加油!!!

你可能感兴趣的:(verilog实战,fpga开发,排序算法,算法)