Home > Software design >  Verilog function gives return clock cycle too late
Verilog function gives return clock cycle too late

Time:07-11

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:

waveform window

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.

  • Related