0
\$\begingroup\$

I'm using Systemverilog interfaces to enable the implementation of generic functions. The interface is defined in one file as follows:

interface interface_onehot_to_binary
# (parameter WIDTH_ONEHOT=16)
(); // Empty port list
localparam WIDTH_BINARY = $clog2 (WIDTH_ONEHOT) ;
 function logic [WIDTH_BINARY-1:0] onehot_to_binary
 (logic [WIDTH_ONEHOT-1: 0] onehot);
 automatic 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
endinterface

And then instantiated in another file as follows:

interface_onehot_to_binary
#(.WIDTH_ONEHOT(256))
inst_interface_onehot_to_binary
(); // Empty port list

The simulation and synthesis tools that I use digest this code without issues. But the SpyGlass linter fails with the following error message: interface 'interface_onehot_to_binary' declaration does not have a modport definition. The error points to the first file - where the interface is defined. What's wrong with my code? How can it be solved?

asked Feb 19, 2021 at 21:23
\$\endgroup\$
4
  • 1
    \$\begingroup\$ This seems like a strange use of an interface. Why not put your function in a package? \$\endgroup\$ Commented Feb 19, 2021 at 22:36
  • \$\begingroup\$ Because I want the function to be generic. To my understanding, if I store the function in a package I'll have to statically declare WIDTH_ONEHOT using a localparam in that package. An interface on the other hand allows me to pass the width using a parameter. \$\endgroup\$ Commented Feb 19, 2021 at 23:05
  • 1
    \$\begingroup\$ You can make the function a static method of a parameterized class. (and synthesizable). \$\endgroup\$ Commented Feb 19, 2021 at 23:25
  • \$\begingroup\$ I would love to learn that. Can you please post an example of my function modified to the form that you mentioned ? \$\endgroup\$ Commented Feb 19, 2021 at 23:40

1 Answer 1

1
\$\begingroup\$
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

Note that even though onehot_to_binary has a static class qualifier, the function has an automatic lifetime.

You would call this using class_onehot_to_binary#(32)::onehot_to_binary(value)

answered Feb 20, 2021 at 3:03
\$\endgroup\$
1
  • \$\begingroup\$ Thanks! If the class is declared in a package - shouldn't we call it as some_pkg::class_onehot_to_binary#(32)::onehot_to_binary(value) ? \$\endgroup\$ Commented Feb 20, 2021 at 12:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.