2014-12-12 4 views
0

Я реализую сортировку оболочки в коде Verilog. У меня есть массив, состоящий из 10 элементов, каждый по 20 бит. Я не могу правильно передать входные значения внутри тестового стенда в регистры внутри модуля. Вот результат:Verilog: ошибка при отображении многобайтового массива (вывод состоит из X, Z, 0)

enter image description here

Вот мой код:

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 

Вот испытательный стенд:

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 

Почему программа производит ошибочное отображение?

+0

Вы пробовали инициализацию свои arr0 ... 9 с 0-й в начале? во время 0 большинство вещей - 'x'. и вы полагаетесь на порядок выполнения, чтобы назначить значения 'inputArrShellSort' перед запуском своего начального блока. – Morgan

+0

Я скопировал код [EDAplayground] (http://www.edaplayground.com/x/BeE) и запустил его с Icarus Verilog 0.9.7. и другие симуляторы. Я не могу воспроизвести вывод, который вы видите. _FYI_: синхронная логика должна быть чувствительной только к одному фронту такта, а не к обоим. Кроме того, я рекомендую начать с включенного сброса и отключить его после первого или второго такта. – Greg

ответ

0

По-видимому, входы от испытательного стенда были неправильно выбрасываны в основной модуль. Вот рабочий алгоритм сортировки (хотя и немного другой), выполненный в 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 

Испытательный стенд:

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