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:
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?
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.
Test bench: