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 位。
由于该问题也被标记为“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)
默认情况下,模块内声明的所有函数都是静态的。
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 节)。创建虚拟类的对象会导致编译错误。这强制执行该方法的严格静态使用。