Reputation: 79
I am trying to build a module for practice which gets as input:
The final purpose is to return in the output the minimum value in the array but I can't get it really working and I don't understand why.
module minVal(
input logic rstN, clk,
input logic unsigned [2:0][3:0] resArray,
output logic [3:0] minVal
);
logic unsigned [3:0] currRes;
always_ff @(posedge clk, posedge rstN) begin
if(rstN == 1'b1) begin
currRes <= 4'b1111;
end
else begin
for(int i = 0; i < 3; i++) begin
if( resArray[i] < currRes) begin
currRes <= resArray[i];
minVal <= resArray[i];
end
end
end
end
endmodule
I wrote the following test bench:
module minVal_tb();
logic rstN, clk;
logic unsigned [2:0][3:0] resArray;
logic [3:0] minVal;
minVal thisInst(.rstN(rstN), .clk(clk), .resArray(resArray), .minVal(minVal));
always begin
#20 clk = ~clk;
end
initial begin
clk = 1'b0;
rstN = 1'b1;
resArray[0] = 5;
resArray[1] = 1;
resArray[2] = 3;
#5 rstN = 1'b0;
end
endmodule
I expect the output to be 1 right after the first clock cycle, but I get it only after 2 clock cycles. Why?
Upvotes: 2
Views: 813
Reputation: 62237
When you unroll the for
loop, this is what it would look like:
always_ff @(posedge clk, posedge rstN) begin
if(rstN == 1'b1) begin
currRes <= 4'b1111;
end
else begin
if( resArray[0] < currRes) begin
currRes <= resArray[0];
minVal <= resArray[0];
end
if( resArray[1] < currRes) begin
currRes <= resArray[1];
minVal <= resArray[1];
end
if( resArray[2] < currRes) begin
currRes <= resArray[2];
minVal <= resArray[2];
end
end
end
You end up with multiple nonblocking assignments to the same register (currRes
).
On the 1st posedge of the clock after reset, all 3 if
clauses are true, and the last assignment wins:
currRes <= resArray[2];
So, currRes
is assigned the value 3, not 1.
The same is true of minVal
.
You need to sort the 3 input values, then compare the minimum of those values to the current minimum.
Upvotes: 1