cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
shaikon
Voyager
Voyager
815 Views
Registered: ‎04-12-2012

Calling a function from a class

Jump to solution

In a file named: "package_functions" I defined a class and a member function as follows:

 

pacakge package_functions ;

class class_onehot_to_binary

# (parameter WIDTH_ONEHOT=16);

localparam WIDTH_BINARY = $clog2 (WIDTH_ONEHOT) ;
static function logic [WIDTH_BINARY-1:0] onehot_to_binary (logic [WIDTH_ONEHOT-1: 0] onehot);
    logic [WIDTH_BINARY-1:0] binary=0;
    foreach (onehot[index])
    begin
       if (onehot[index]==1'b1) begin
          binary=binary|index;
       end
    end
    return binary;
endfunction

endclass

/*
Lots of other classes, functions and variables are also declared in this file...
*/

endpackage

 

I want to make (all) the contents of "package_functions" visible to another module declared in a different file - named: "some_module.sv".
So inside "some_module.sv" - I do a wildcard import as follows:

 

module some_module
import package_functions :: * ;

// Now I want to use class_onehot_to_binary. So I instantiate it:

class_onehot_to_binary #(.WIDTH_ONEHOT ( 8 )) class_onehot_to_binary_inst

// And try to call the function as follows:

assign binary_value = class_onehot_to_binary_inst.onehot_to_binary ( onehot_value ) ;

 

But this gives an error: "unxpected type name. The type class_onehot_to_binary is defined at package_functions.sv" 
How can I fix this ?

0 Kudos
1 Solution

Accepted Solutions
markcurry
Scholar
Scholar
649 Views
Registered: ‎09-16-2009

>assign class_onehot_to_binary_inst = new ( ) ;

No, this will not work - this is a continuous assignment - which must be applied to a net type - not a variable (which is what a class object is)

You must construct the class object either within a procedural context (an initial or always block), or alternatively as part of the declaration initializer.

An example of the latter:

 

class_onehot_to_binary #
(
    .WIDTH_ONEHOT ( 8 )
) class_onehot_to_binary_inst = new();

// Call the member function :
assign binary_value = class_onehot_to_binary_inst.onehot_to_binary(onehot_value);

 

Regards,

Mark

View solution in original post

6 Replies
markcurry
Scholar
Scholar
737 Views
Registered: ‎09-16-2009

Normally, one needs to construct a class object in order to use it's members methods - you're never creating a new class object in your example, just declaring the class variable. 

Luckily, SystemVerilog does you give some abilities to call an unconstructed method in some cases.  See the section of the Systemverilog standard "8.25.1 Class resolution operator for parameterized classes" for examples.

TL/DR:

assign binary_value = package_functions::class_onehot_to_binary#( .WIDTH_ONEHOT( 8 ) )::onehot_to_binary( onehot_value );

However, you're asking this question within the Synthesis group.  I believe none of this is synthesizable within Vivado.

Regards,

Mark

shaikon
Voyager
Voyager
688 Views
Registered: ‎04-12-2012

Thanks. Can you give an example of a class constructor with context to my code?

0 Kudos
markcurry
Scholar
Scholar
672 Views
Registered: ‎09-16-2009

> Can you give an example of a class constructor with context to my code?

initial class_onehot_to_binary_inst  = new();

Regards,

Mark

shaikon
Voyager
Voyager
652 Views
Registered: ‎04-12-2012

Thanks,

I understand your example from ‎02-22-2021 10:39 AM. But will the following syntax also be valid ( if Vivado supported classes for synthesis ) ?

// In the module - import the package where the class is declared :
module some_module
import package_functions :: * ;

// Instantiate the class :
class_onehot_to_binary #
(
    .WIDTH_ONEHOT ( 8 )
) class_onehot_to_binary_inst

// Construct it :
assign class_onehot_to_binary_inst = new ( ) ; // not using initial ( because it's for synthesis ).

// Call the member function :
assign binary_value = class_onehot_to_binary_inst.onehot_to_binary ( onehot_value ) ;
0 Kudos
markcurry
Scholar
Scholar
650 Views
Registered: ‎09-16-2009

>assign class_onehot_to_binary_inst = new ( ) ;

No, this will not work - this is a continuous assignment - which must be applied to a net type - not a variable (which is what a class object is)

You must construct the class object either within a procedural context (an initial or always block), or alternatively as part of the declaration initializer.

An example of the latter:

 

class_onehot_to_binary #
(
    .WIDTH_ONEHOT ( 8 )
) class_onehot_to_binary_inst = new();

// Call the member function :
assign binary_value = class_onehot_to_binary_inst.onehot_to_binary(onehot_value);

 

Regards,

Mark

View solution in original post

markcurry
Scholar
Scholar
649 Views
Registered: ‎09-16-2009

You appear to desire to use parameterized functions.  A synthesizable way to do this (which is supported within Vivado) is discussed here:

https://forums.xilinx.com/t5/Synthesis/Synthesizing-SystemVerilog-parametrized-functions-in-Vivado-2016/td-p/773272

Regards,

Mark