Verilog: Error in displaying multibit array (output consisting of X, Z, 0)

716 views Asked by At

I'm implementing shell sort in Verilog code. I have an array consisting of 10 elements, each 20-bits wide. I can't get to pass the input values properly inside the test bench to the registers inside the module. Here's the output:

enter image description here

Here's my code:

module DoShellSort(
    input reset,
    input clk,
    input [199:0] inputArrShellSort,
    output reg [199:0] outputArrShellSort
    ); 

    reg [3:0] gap;
    reg [3:0] i;
    reg [3:0] j;
    reg [3:0] arrayLength;
    reg [19:0] temp;

    reg [2:0] currentState;

    reg [19:0] arr0;
    reg [19:0] arr1;
    reg [19:0] arr2;
    reg [19:0] arr3;
    reg [19:0] arr4;
    reg [19:0] arr5;
    reg [19:0] arr6;
    reg [19:0] arr7;
    reg [19:0] arr8;
    reg [19:0] arr9;

    //******************************
    // Perform shell sort
    //******************************

    initial begin 
        currentState <= 4'd0;
        gap <= 4'd5;
        arrayLength <= 4'd10;
        arr0[19:0] <= inputArrShellSort[19:0]   ;
        arr1[19:0] <= inputArrShellSort[39:20]  ;
        arr2[19:0] <= inputArrShellSort[59:40]  ;
        arr3[19:0] <= inputArrShellSort[79:60]  ;
        arr4[19:0] <= inputArrShellSort[99:80]  ;
        arr5[19:0] <= inputArrShellSort[119:100];
        arr6[19:0] <= inputArrShellSort[139:120];
        arr7[19:0] <= inputArrShellSort[159:140];
        arr8[19:0] <= inputArrShellSort[179:160];
        arr9[19:0] <= inputArrShellSort[199:180];       
    end

    always @ (posedge clk or negedge clk) begin
        if (reset == 1) begin 
            currentState <= 3'd0;
            gap <= 4'd5;
            arrayLength <= 4'd10;
            arr0[19:0] <= inputArrShellSort[19:0]   ;
            arr1[19:0] <= inputArrShellSort[39:20]  ;
            arr2[19:0] <= inputArrShellSort[59:40]  ;
            arr3[19:0] <= inputArrShellSort[79:60]  ;
            arr4[19:0] <= inputArrShellSort[99:80]  ;
            arr5[19:0] <= inputArrShellSort[119:100];
            arr6[19:0] <= inputArrShellSort[139:120];
            arr7[19:0] <= inputArrShellSort[159:140];
            arr8[19:0] <= inputArrShellSort[179:160];
            arr9[19:0] <= inputArrShellSort[199:180];
        end
        else begin
            case (currentState)
                3'd0: begin                     
                                    //outputArrShellSort[19:0]    <= arr0[19:0];
                                    //outputArrShellSort[39:20]   <= arr1[19:0];
                                    //outputArrShellSort[59:40]   <= arr2[19:0];
                                    //outputArrShellSort[79:60]   <= arr3[19:0];
                                    //outputArrShellSort[99:80]   <= arr4[19:0];
                                    //outputArrShellSort[119:100] <= arr5[19:0];
                                    //outputArrShellSort[139:120] <= arr6[19:0];
                                    //outputArrShellSort[159:140] <= arr7[19:0];
                                    //outputArrShellSort[179:160] <= arr8[19:0];
                                    //outputArrShellSort[199:180] <= arr9[19:0];
                                    outputArrShellSort[199:0] <= inputArrShellSort[199:0];
                                    currentState <= 3'd1;
                                    end
                3'd1: begin
                                    if (gap > 0) currentState <= 3'd2;
                                    else currentState <= 3'd5;
                                    end
                3'd2: begin
                                    i <= gap;
                                    currentState <= 3'd3;
                                    end
                3'd3: begin
                                    if (i < arrayLength) begin
                                        j <= i;
                                        // temp <= outputArrShellSort[i]; // <---------
                                        case(i)
                                            4'd0: temp <= arr0;
                                            4'd1: temp <= arr1;
                                            4'd2: temp <= arr2;
                                            4'd3: temp <= arr3;
                                            4'd4: temp <= arr4;
                                            4'd5: temp <= arr5;
                                            4'd6: temp <= arr6;
                                            4'd7: temp <= arr7;
                                            4'd8: temp <= arr8;
                                            4'd9: temp <= arr9;                                         
                                        endcase
                                        currentState <= 3'd4;
                                    end
                                    else begin
                                        if (gap == 2) gap <= 1;
                                        else gap <= gap * (5/11);
                                        currentState <= 1;
                                    end
                                    end
                3'd4: begin
                                    // if (j >= gap && outputArrShellSort[j-gap] >= temp) begin
                                        // outputArrShellSort[j] <= outputArrShellSort[j-gap];
                                        // j <= j-gap;
                                        // currentState <= 3'd4;
                                    // end 
                                    if (j >= gap) begin
                                        case (gap)   
                                            4'd5: begin
                                                        if (arr9 >= temp) begin
                                                            arr5 <= arr9;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr8 >= temp) begin
                                                            arr3 <= arr8;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr7 >= temp) begin
                                                            arr2 <= arr7;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr6 >= temp) begin
                                                            arr1 <= arr6;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end 
                                                        if (arr5 >= temp) begin
                                                            arr0 <= arr5;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end                                                             
                                                        end 
                                            4'd2: begin
                                                        if (arr9 >= temp) begin
                                                            arr7 <= arr9;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr8 >= temp) begin
                                                            arr5 <= arr8;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr7 >= temp) begin
                                                            arr4 <= arr7;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr6 >= temp) begin
                                                            arr3 <= arr6;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end 
                                                        if (arr5 >= temp) begin
                                                            arr2 <= arr5;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end                                                             
                                                        if (arr4 >= temp) begin
                                                            arr1 <= arr4;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr3 >= temp) begin
                                                            arr0 <= arr3;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end                                                 
                                                        end                                                     
                                            4'd1: begin 
                                                        if (arr9 >= temp) begin
                                                            arr8 <= arr9;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr8 >= temp) begin
                                                            arr7 <= arr8;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr7 >= temp) begin
                                                            arr6 <= arr7;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr6 >= temp) begin
                                                            arr5 <= arr6;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end 
                                                        if (arr5 >= temp) begin
                                                            arr4 <= arr5;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end                                                             
                                                        if (arr4 >= temp) begin
                                                            arr3 <= arr4;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr3 >= temp) begin
                                                            arr2 <= arr3;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end     
                                                        if (arr2 >= temp) begin
                                                            arr1 <= arr2;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end
                                                        if (arr1 >= temp) begin
                                                            arr0 <= arr1;
                                                            j <= j-gap;
                                                            currentState <= 3'd4;
                                                            end                                                             
                                                        end
                                        endcase
                                    end 
                                    else begin
                                        //outputArrShellSort[j] <= temp; // <---------
                                        case (j)
                                            4'd0: arr0 <= temp;
                                            4'd1: arr1 <= temp;
                                            4'd2: arr2 <= temp;
                                            4'd3: arr3 <= temp;
                                            4'd4: arr4 <= temp;
                                            4'd5: arr5 <= temp;
                                            4'd6: arr6 <= temp;
                                            4'd7: arr7 <= temp;
                                            4'd8: arr8 <= temp;
                                            4'd9: arr9 <= temp;                                         
                                        endcase
                                        currentState <= 3'd2;
                                    end
                                    end
                3'd5: begin
                                    outputArrShellSort[199:0] <= {arr9[19:0], arr8[19:0], arr7[19:0], arr6[19:0], 
                                                                  arr5[19:0], arr4[19:0], arr3[19:0], arr2[19:0], 
                                                                  arr1[19:0], arr0[19:0]};
                                    end         
                default:            currentState <= 3'd0;                               
            endcase
        end
    end
endmodule

Here's the test bench:

module ShellSort_tb();
    reg reset;
    reg clk;
    reg [199:0] inputArrShellSort;
    wire [199:0] outputArrShellSort;

    DoShellSort SHELLSORT(.reset(reset),
                    .clk(clk),
                    .inputArrShellSort(inputArrShellSort),
                    .outputArrShellSort(outputArrShellSort)
                    );  

    // Input values you want to sort here
    // Note: Should be 20 bits in size
    initial begin
        inputArrShellSort[19:0]    = 20'hbac23;
        inputArrShellSort[39:20]   = 20'hc4827;
        inputArrShellSort[59:40]   = 20'hef3bb;
        inputArrShellSort[79:60]   = 20'he0594;
        inputArrShellSort[99:80]   = 20'hf991e;
        inputArrShellSort[119:100] = 20'h9febb;
        inputArrShellSort[139:120] = 20'h14213;
        inputArrShellSort[159:140] = 20'h79cfc;
        inputArrShellSort[179:160] = 20'h8c544;
        inputArrShellSort[199:180] = 20'hbb222; 
    end

    initial begin
        clk <= 0;
        reset <= 0; 
    end

    initial begin
        $display("*********************************************");
        $display("      SHELL SORT");
        $display("*********************************************\n");
        // Display initial array
        $display("\nTo sort:\t%h %h %h %h %h %h %h %h %h %h\n\n", inputArrShellSort[19:0], inputArrShellSort[39:20], inputArrShellSort[59:40], 

        inputArrShellSort[79:60], inputArrShellSort[99:80], inputArrShellSort[119:100], 
        inputArrShellSort[139:120], inputArrShellSort[159:140], inputArrShellSort[179:160], inputArrShellSort[199:180]);



        $display("clk\t\tSorted Array");
        $display("---------------------------------------------------------------------------");
        $monitor("%b\t\t%h %h %h %h %h %h %h %h %h %h", clk, outputArrShellSort[19:0], outputArrShellSort[39:20], outputArrShellSort[59:40],
        outputArrShellSort[79:60], outputArrShellSort[99:80], outputArrShellSort[119:100], 
        outputArrShellSort[139:120], outputArrShellSort[159:140], outputArrShellSort[179:160], outputArrShellSort[199:180]);

        end 

    initial begin
        repeat(20)
    #10 clk <= ~clk;
    $finish;
    end

endmodule

Why is the program producing the erroneous display?

1

There are 1 answers

0
ellekaie On

Apparently, the inputs from test bench were not properly thrown to the main module. Here's a working sorting algorithm (albeit slightly different) done in HDL.

module selectionSort(listOut, listIn, start, reset, clk);
    output [199:0] listOut;
    input [199:0] listIn;
    input start, reset, clk;

    parameter S0=2'b00, S1=2'b01, S2=2'b10;
   reg [19:0] list [0:9];
    reg [3:0] inner, outer, smallest;
    reg [1:0] state=S0;

    always @(posedge clk or posedge reset) begin
        if(reset) begin
            state <= S0;
        end
        else begin
            case(state)
            S0: begin
                if(!start) begin
                    state <= S0;
                end
                else begin
                    outer <= 0;
                    inner <= 0;
                    {list[0], list[1], list[2], list[3], list[4], list[5], list[6], list[7], list[8], list[9]} <= listIn;
                    state <= S1;
                end
            end

            S1: begin
                smallest <= outer;
                if(outer == 9) begin
                    state <= S0;
                end
                else begin
                    inner <= outer;
                    state <= S2;
                end
            end

            S2: begin
                if(inner == 10) begin
                    outer <= outer + 1;
                    list[outer] <= list[smallest];
                    list[smallest] <= list[outer];
                    state <= S1;
                end
                else begin
                    if(list[smallest] > list[inner]) begin
                        smallest <= inner;
                        inner <= inner + 1;
                        state <= S2;
                    end
                    else begin
                        inner <= inner + 1;
                        state <= S2;
                    end
                end
            end
            endcase
        end
    end

    assign listOut = {list[0], list[1], list[2], list[3], list[4], list[5], list[6], list[7], list[8], list[9]};
endmodule

Test bench:

module testbench;
    wire [199:0] listOut;
    reg [199:0] listIn;
    reg start, reset, clk;
    reg [19:0] list [0:9];
    time t1, t2, t3;

    selectionSort testRun(listOut, listIn, start, reset, clk);

    always #1 begin
        clk=~clk;
        if ($time == t2) begin
            start=0;
        end
        if ($time == t3) begin
            start=0;
            reset=0;
        end
    end

    always @(posedge start, posedge reset)begin
        if(reset) t3 = $time + 1;
        else begin
            if(clk) t1 = $time;
            else t1 = $time + 1;
            t2 = t1 + 145;
        end
    end

    always @(listOut, posedge start, posedge reset) begin
        if ($time == 0 || listOut === 200'bz || reset == 1) begin
            if(reset && listOut !== 200'bz) $display($time, "    %b     %b    |   %0h %0h %0h %0h %0h %0h %0h %0h %0h %0h Reset Pressed", start, reset, listOut[199:180], listOut[179:160], listOut[159:140], listOut[139:120], listOut[119:100], listOut[99:80], listOut[79:60], listOut[59:40], listOut[39:20], listOut[19:0]);
        end
        else begin
            $display($time, "    %b     %b    |   %0h %0h %0h %0h %0h %0h %0h %0h %0h %0h", start, reset, listOut[199:180], listOut[179:160], listOut[159:140], listOut[139:120], listOut[119:100], listOut[99:80], listOut[79:60], listOut[59:40], listOut[39:20], listOut[19:0]);
        end
    end

    initial begin
        start = 0; reset = 0; clk = 0;
        listIn = {20'd0, 20'd0, 20'd0, 20'd0, 20'd0, 20'd0, 20'd0, 20'd0, 20'd0, 20'd0};
        $display("\nSelection Sort\n");
        $display("\t\t TIME START RESET  |\t      ARRAY");
    end

    initial fork
        #2 start=1;
        #4 reset=1;
        #7 start=1;
        #7 listIn = {20'd3, 20'd5, 20'd0, 20'd1, 20'd6, 20'd9, 20'd8, 20'd7, 20'd2, 20'd4};
        #201 $display("\t\t-------------------------------------------");
        #200 listIn = {20'hB, 20'h9, 20'h3, 20'hC, 20'h5, 20'hE, 20'h7, 20'hF, 20'h1, 20'h0};
        #200 start=1;
        #338 reset=1;
        #1000 $finish;
    join
endmodule