将参数传递给 Verilog 函数

R.M*_*mey 4 verilog system-verilog

我想将参数传递给函数并将其用作参数(例如选择位),但我不知道如何告诉函数此输入是常量。

例如,如果我想这样做:

assign foo = bar[MY_PARAM:0];
Run Code Online (Sandbox Code Playgroud)

我想写my_function这样我就可以做到这一点:

assign foo = my_function(bar, MY_PARAM);
Run Code Online (Sandbox Code Playgroud)

就我而言,我需要做更多的事情,只是选择位,但不要太多,并且我希望它适用于不同位宽度的输入。如果我只是想选择一点,我可以使用下面的函数,我希望有一个类似形式的解决方案,但我无法计算出语法:

function my_function;
  input [3:0] data, my_bit;
  begin
    my_function = data[my_bit];
  end
endfunction
Run Code Online (Sandbox Code Playgroud)

根据 Silicon1602 的回答,我需要的代码是:

virtual class myClass#(parameter LOCAL_PARAM);
  static function [LOCAL_PARAM:0] my_function;
    input [LOCAL_PARAM:0] data;
    begin
      my_function = data[LOCAL_PARAM:0];
    end
  endfunction
endclass
assign foo = myClass#(MY_PARAM)::my_function(bar);
Run Code Online (Sandbox Code Playgroud)

起初我忘记了这个[LOCAL_PARAM]部分,只是恢复了 1 位。

Ser*_*rge 8

由于该问题也被标记为“verilog”,因此可以在简单的 verilog 中使用类似的技巧。您可以使用参数化模块来达到相同的效果。例如:

module util#(
  parameter int W = 10)();

  function funct;
    input [W-1:0] inp;
    funct = inp;
  endfunction

endmodule


module top(out, in);
  parameter W = 8;

  output wire [W-1:0] out;
  input wire [W-1:0] in;  

  util#(W) u1(); // inst util module with a parameter
  assign out = u1.funct(in); // call the function

  initial #1 $finish;

endmodule
Run Code Online (Sandbox Code Playgroud)

默认情况下,模块内声明的所有函数都是静态的。


Sil*_*602 6

SystemVerilog LRM有一个关于您的特定情况的部分:13.8 参数化任务和函数。它说:

SystemVerilog 提供了一种创建参数化任务和函数的方法,也称为参数化子例程。[...] 实现参数化子例程的方法是通过在参数化类中使用静态方法(参见 8.10 和 8.25)。

在你的情况下,你应该像这样声明你的函数:

virtual class myClass#(parameter MY_PARAM);
    static function my_function;
        input [MY_PARAM-1:0] data, my_bit;
        begin
            my_function = data[my_bit];
        end
    endfunction
endclass
Run Code Online (Sandbox Code Playgroud)

然后你可以这样调用你的函数:

assign my_function_output = myClass#(MY_PARAM)::my_function(data, my_bit);
Run Code Online (Sandbox Code Playgroud)

请注意,您可以在抽象类中声明多个函数。因此,如果您有一大堆函数都以相同的方式依赖于一个参数,那么您可以将它们全部声明在同一个类中。


关于上述上下文中的virtualand关键字的一些附加信息:static

LRM 第 8.10 节讨论了static方法。

静态方法受所有类作用域和访问规则的约束,但其行为类似于可以在类外部调用的常规子例程,即使没有类实例化也是如此。静态方法无法访问非静态成员(类属性或方法),但可以直接访问静态类属性或调用同一类的静态方法。

通过使用virtual类声明的关键字,您可以向编译器表明这是一个抽象类(请参阅 LRM 中的第 8.21 节)。创建虚拟类的对象会导致编译错误。这强制执行该方法的严格静态使用。