将参数传递给 Verilog 函数
Passing parameters to a Verilog function
我想将参数传递给函数并将其用作参数(例如 select 位)但我不知道如何告诉函数此输入是常量。
例如,如果我想这样做:
assign foo = bar[MY_PARAM:0];
我想写 my_function
这样我就可以这样做:
assign foo = my_function(bar, MY_PARAM);
在我的例子中,我需要做的只是 select 位,但不要太多,我希望它适用于不同位宽的输入。
如果我只是想 select 一点,我可以使用下面的函数,我希望有一个类似形式的解决方案,但我无法计算出语法:
function my_function;
input [3:0] data, my_bit;
begin
my_function = data[my_bit];
end
endfunction
根据 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);
起初我忘记了 [LOCAL_PARAM]
部分,只是得到 1 位。
SystemVerilog LRM 中有一节是关于您的特定案例的:13.8 参数化任务和函数。它说:
SystemVerilog provides a way to create parameterized tasks and functions, also known as parameterized subroutines. [...] The way to implement parameterized subroutines is through the use of static methods in parameterized classes (see 8.10 and 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
然后您可以这样调用您的函数:
assign my_function_output = myClass#(MY_PARAM)::my_function(data, my_bit);
请注意,您可以在摘要中声明多个函数 class。所以,如果你有一大堆函数都以相同的方式依赖于一个参数,你可以在相同的 class.
中声明它们
关于上述上下文中 virtual
和 static
关键字的一些附加信息:
LRM 的第 8.10 节讨论了 static
方法。
A static method is subject to all the class scoping and access rules, but behaves like a regular subroutine that can be called outside the class, even with no class instantiation. A static method has no access to non-static members (class properties or methods), but it can directly access static class properties or call static methods of the same class.
通过对 class 声明使用 virtual
关键字,您向编译器表明这是一个抽象 class(请参阅 LRM 中的第 8.21 节)。创建虚拟 class 的对象会导致编译错误。这强制严格静态使用该方法。
由于问题也被标记为 '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
默认情况下,模块中声明的所有函数都是静态的。
我想将参数传递给函数并将其用作参数(例如 select 位)但我不知道如何告诉函数此输入是常量。
例如,如果我想这样做:
assign foo = bar[MY_PARAM:0];
我想写 my_function
这样我就可以这样做:
assign foo = my_function(bar, MY_PARAM);
在我的例子中,我需要做的只是 select 位,但不要太多,我希望它适用于不同位宽的输入。 如果我只是想 select 一点,我可以使用下面的函数,我希望有一个类似形式的解决方案,但我无法计算出语法:
function my_function;
input [3:0] data, my_bit;
begin
my_function = data[my_bit];
end
endfunction
根据 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);
起初我忘记了 [LOCAL_PARAM]
部分,只是得到 1 位。
SystemVerilog LRM 中有一节是关于您的特定案例的:13.8 参数化任务和函数。它说:
SystemVerilog provides a way to create parameterized tasks and functions, also known as parameterized subroutines. [...] The way to implement parameterized subroutines is through the use of static methods in parameterized classes (see 8.10 and 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
然后您可以这样调用您的函数:
assign my_function_output = myClass#(MY_PARAM)::my_function(data, my_bit);
请注意,您可以在摘要中声明多个函数 class。所以,如果你有一大堆函数都以相同的方式依赖于一个参数,你可以在相同的 class.
中声明它们关于上述上下文中 virtual
和 static
关键字的一些附加信息:
LRM 的第 8.10 节讨论了 static
方法。
A static method is subject to all the class scoping and access rules, but behaves like a regular subroutine that can be called outside the class, even with no class instantiation. A static method has no access to non-static members (class properties or methods), but it can directly access static class properties or call static methods of the same class.
通过对 class 声明使用 virtual
关键字,您向编译器表明这是一个抽象 class(请参阅 LRM 中的第 8.21 节)。创建虚拟 class 的对象会导致编译错误。这强制严格静态使用该方法。
由于问题也被标记为 '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
默认情况下,模块中声明的所有函数都是静态的。