我在Verilog代码中实现shell排序。我有一个由10个元素组成的数组,每个元素都是20位宽。我无法将测试平台内的输入值正确传递给模块内的寄存器。这是输出:
这是我的代码:
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 :(得分: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