I created a module that first sorts a byte array then choose last element as minimum.(just for practice). When I moved sort to the task block, it doesn't worked as well as before. How can use task block properly for sorting ? thanks.
Sort without task:
module sort(input clk, input nrst, output byte choose);
byte sorted[0:3];
assign choose = sorted[3];// output must be minimum after sort (12)
always@(posedge clk, negedge nrst) begin
if(nrst == 0) begin // initialize to something
sorted[0] = 17;
sorted[1] = 12;
sorted[2] = 23;
sorted[3] = 21;
end
else begin
int i, j;
byte tmp;
//sort
for(i=0; i<4; i=i+1)
for(j=0; j<4; j=j+1)
if(sorted[j] < sorted[j+1]) begin
tmp = sorted[j]; // swap
sorted[j] = sorted[j+1];
sorted[j+1] = tmp;
end
end
end
endmodule
Sort with Task:
module sort(input clk, input nrst, output byte choose);
byte sorted[0:3];
assign choose = sorted[3];// output must be minimum after sort (12)
always@(posedge clk, negedge nrst) begin
if(nrst == 0) begin // initialize to something
sorted[0] = 17;
sorted[1] = 12;
sorted[2] = 23;
sorted[3] = 21;
end
else begin
sort_task(sorted);
end
end
task sort_task(inout byte list[3:0]);
begin
int i, j;
byte tmp;
//sort
for(i=0; i<4; i=i+1)
for(j=0; j<4; j=j+1)
if(list[j] < list[j+1]) begin
tmp = list[j];
list[j] = list[j+1];
list[j+1] = tmp;
end
end
endtask
endmodule
Testbench:
module tb();
byte choose;
reg nrst, clk;
sort sort(clk, nrst, choose);
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
int i;
nrst = 1;
#50;
for(i=0; i<4; i=i+1)
$display("50 : %d", sort.sorted[i]);
nrst = 0;
#50
for(i=0; i<4; i=i+1)
$display("100 : %d", sort.sorted[i]);
nrst = 1;
#50
for(i=0; i<4; i=i+1)
$display("150: %d", sort.sorted[i]);
end
endmodule
Best Answer
The problem is there is a mismatch in the index declaration for
sorted[0:3]
versuslist[3:0]
, so(list[j] < list[j+1])
gives you the reverse evaluation. I strongly recommend using common typedef's (in a package) to eliminate problems like this.BTW, using a typedef gives you the syntax needed to declare a function with unpacked return type because any simple name is allowed for a return type, no matter how complex the typedef is.
Also, I agree with you that a task is synthesizable, as long as the code inside the task is meets your tools synthesis modelling style. But I would prefer that people use a void function instead of a task when their task has no time consuming statements. A function is a guarantee that it will not consume time.