1

Here is a small tb, with some example code, where I am trying to define a function two ways, then call that fn below its definition.

module tryfact;
  
  localparam FUNCTION_IS_STATIC = 1;
  
  generate :mygen
    
  if(FUNCTION_IS_STATIC)
      // static fn
      function  integer factorial (input [31:0] operand);
        factorial = 1;
      endfunction: factorial
    
      else
      // automatic fn
      function automatic integer factorial (input [31:0] operand);
        factorial = 1;
      endfunction: factorial
      
  endgenerate :mygen
    
  // test the function
  begin
  integer result;
  initial begin
    result = mygen.factorial(1);
    $display("%0d factorial=%0d", 1, result);
    end
  end
  
endmodule

If I name the block so that it can be called using mygen.factorial1, simulation errors producing:

generate :mygen
           |
xmvlog: *E,UMGENE (testbench.sv,5|11): An 'endgenerate' is expected [12.1.3(IEEE 2001)].
  generate :mygen
           |
xmvlog: *E,EXPENM (testbench.sv,5|11): expecting the keyword 'endmodule' [12.1(IEEE)].
endmodule

If I remove the block label, its fine with the generate, but now I have no hierarchical reference.

xmelab: *E,CUVUNF (./testbench.sv,25|23): Hierarchical name component lookup failed for 'factorial' at 'tryfact'.

How should the generate be named with a single name so that it can be hierarchicaly referenced by that name when called?

1 Answer 1

2

This compiles and runs for me without errors on Cadence and Synopsys simulators:

module tryfact;
  
  localparam FUNCTION_IS_STATIC = 1;
  
  if (FUNCTION_IS_STATIC) begin : mygen

      function  integer factorial (input [31:0] operand);
        factorial = 1;
      endfunction: factorial
    
  end else begin : mygen

      function automatic integer factorial (input [31:0] operand);
        factorial = 1;
      endfunction: factorial
      
  end
    
  // test the function
  begin
    integer result;
    initial begin
        result = mygen.factorial(1);
        $display("%0d factorial=%0d", 1, result);
    end
  end
  
endmodule

I added begin/end keywords on each branch of the if/else, and added the mygen label on each branch.

Refer to IEEE Std 1800-2023, section 27.5 Conditional generate constructs

I removed the optional generate/endgenerate keywords. I don't think adding a label after the generate keyword is legal syntax.

Sign up to request clarification or add additional context in comments.

1 Comment

I did not realize the same label could be used in both branches if the if. It makes sense bc only one branch is elaborated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.