Search code examples
verilogxilinx-ise

for-loops in function


I have some questions about timing in verilog when using a for-loop in a function.

  1. How do I estimate the clock cycles needed to execute a function in which a for-loop is operating?

  2. And how can I estimate the clock time needed for one for-loop iteration.

  3. Does a function works something like an interrupt. For example: If I call a function in sequential logic, than everything is halted until the function finishes?

[Update] Here is some more information about for what I'm using the for-loops exactly.

integer n;

 always@(posedge CLK)
     if(IN)              // some input wire IN   
       begin
         n = n + 1;
         Result[31:0] <= Approx(n); //put Result from Approx into output reg Result
       end

 function [31:0] Approx
    input n;
     integer n;
     real fp;  //some real number to store the approximation result
    begin
      for(integer i=0; i < 2**16; i=i+1) 
         begin
       ... // do Approximation within fixed iteration steps
       ... // Result is a floating point number
         end
     Approx[31:0] = convert_fp_to_bin(fp); //another function with for-loop to convert decimal number into binary number
    end
     ....

Solution

  • The Verilog function construct does not allow delays or any timing constructs (such as #, @, wait, etc) inside them; ie, functions are not allowed to take any more than 0 simulation time. Thus, a function will always complete in 0 time, so 0 clock cycles. For-loops are certainly allowed inside functions, however, these for-loops must not have any timing constructs, so they will execute in 0 time. So, if a function call is made anywhere, the function will run and a value be determined at the time the line is executed (in general, there might be strange cases where this is not true, but youd have to check the LRM for information on these cases).

    For a short example, say you have a functions called flip the just flips the bits of a given, 4bit vector. Then, say you have the following code:

    initial begin
      ...
      a = flip(b);
      ... // No timing constructs in here
      #10;
      ...
    end
    
    always @(*) begin
      d = flip(a);
    end
    

    When the initial block hit the line a = flip(b), a will get the value of b will the bit reversed (ie, the function will run, the value returned and a assigned to that value). Once the initial block hits the #10, the always block might fire and assign d the value of a will the bits flipped (ie, the value of b). So, in answer to your 3rd question, functions are executed inline. Note, if you call fork in the function, you can confound this, but for basic functions, you can just think of them as inline.