Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Use if-generate structure to define two variations of a function, and call that function in the same tb

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading