I wrote a function in Verilog to flip the order of bits in a word. The function does what it should but not in the clock cycle it gets called but in the next.
This is function:
function [n-1:0] bitreverse;
input [n-1:0] in;
reg [n:0] idx;
for(idx = 0; idx <= (n-1); idx = idx 1) begin
bitreverse [idx]= in[(n-1)-idx];
end
endfunction
It gets called here:
parameter K = 4;
parameter N = K*2;
parameter n = $clog2(N);
reg [n-1:0] j = 0;
reg [n-1:0] i = 0;
always @(posedge clock)
begin: Decode
if (j <= N-1) begin
i = bitreverse(j);
// some stuff is happening here
j = j 1;
end
end
and the result looks like that:
CodePudding user response:
When you use always @(posedge clock)
, you instruct the simulator to treat i
like it is sequential logic, like a flip flop. The simulator internally samples the return value of the bitreverse
function at the rising edge of the clock, then updates i
at the next rising edge of clock.
If you want i
to behave like combinational logic, where its value will be updated immediately by the simulator, you must not use @(posedge clock)
for i
. You can use @*
instead. For example:
always @*
begin: Decode
if (j <= N-1) begin
i = bitreverse(j);
end else begin
i = j;
end
end
always @(posedge clock) j <= j 1;
For sequential logic, it is recommended to use a nonblocking (<=
) assignment, which is what I showed for j
.