For loops in Verilog are almost exactly like for loops in C or C++. But to group statements the begin-end block is used and the ++ and -- operators are not supported. The full definition of how it exactly work is from the Verilog standard:
"Controls execution of its associated statement(s) by a three-step process, as follows:
a) Executes an assignment normally used to initialize a variable that controls the number of loops executed.
b) Evaluates an expression. If the result is zero, the for loop shall exit. If it is not zero, the for loop shall execute its associated statement(s) and then perform step c). If the expression evaluates to an unknown or high-impedance value, it shall be treated as zero.
c) Executes an assignment normally used to modify the value of the loop-control variable, then repeats step b)."
Simply put, a for loop repeats the statement as long as the loop control variable changes in a given range and satisfies that range.
always @(posedge clk) begin
.................................
waddr_tmp = 0;
if (grant > 0) begin
for (i = $clog2(CHANNEL_NUM)-1; i >= 0; i = i - 1) begin
if (grant[i])
waddr_tmp = waddr_tmp + (mode_i ? (2 << i) : (SINGLE_SIZE << i));
end
end
waddr <= waddr_incr + waddr_tmp;
.................................
end
In some cases it is possible to code an if-else chain using a for-loop:
channel_start <= 0;
for (int i = LINE_NUM; i >= 0; i--) begin
if (received[1][i]) channel_start <= i;
end
or more interesting case with cyclic steps through channels:
if (timestamp_shift_en) begin
timestamp_shiftreg_cnt <= timestamp_shiftreg_cnt + 1;
timestamp_shiftreg[grant] <= {timestamp_shiftreg[grant][SINGLE_SIZE*16-1-16:0], 16'h0};
timestamp_user_data[grant] <= {16'h0, timestamp_user_data[grant][SINGLE_SIZE*16-1:16]};
if ((timestamp_shiftreg_cnt == 4 && mode_i == 1'b0) || (timestamp_shiftreg_cnt == 1 && mode_i == 1'b1)) timestamp_shift_en <= 0;
if (timestamp_shiftreg_cnt == 0) timestamp_shift_en_req[grant] <= 0;
end else begin
for (i = (JOIN_SUBFRAMES ? 0 : CHANNEL_NUM-1); i >= 0; i = i -1) begin
if (timestamp_shift_en_req[(i+(grant+1)%CHANNEL_NUM)%CHANNEL_NUM]) begin
timestamp_shift_en <= 1'b1;
timestamp_shiftreg_cnt <= 0;
grant <= (i+(grant+1)%CHANNEL_NUM)%CHANNEL_NUM;
end
end
end