我需要 Verilog 中的 rightrotate 函数来处理 32 位输入,因为它没有定义为运算符 (x >>> y)。
手动右旋转此类输入很容易:
wire [31:0] test = 32'd12345;
wire [31:0] rotated_1 = {test[0:0],test[31:1]};
wire [31:0] rotated_3 = {test[2:0],test[31:3]};
测试平台的输出符合预期:
original: 00000000000000000011000000111001
rotate_1: 10000000000000000001100000011100
rotate_3: 00100000000000000000011000000111
我们看到,函数rotate(inp,x)应该像这样工作:
function rotate;
input [31:0] inp;
input [4:0] x;
begin
rotate = {inp[x-1:0],inp[31:x]};
end
endfunction
问题是:x 不是常量,因此无法编译。要使用 [a:b] 指定范围,a 和 b 都必须是常量。
解决方案似乎正在使用参数:
function rotate;
parameter integer x = 1;
input [31:0] inp;
begin
rotate = {inp[x-1:0],inp[31:x]};
end
endfunction
嗯,它确实可以编译,但与模块不同,您可以使用更改后的参数实例化模块,如下所示
param_module #(3) pm_inst(...);
,不适用于函数。事实上,从阅读grammar对于 Verilog,我完全看不到指定参数的方法:
<function_call>
::= <name_of_function> ( <expression> <,<expression>>* )
我对 defparam 的实验只适用于模块,不适用于函数。
由于 Verilog 中也不存在参数化宏,我应该如何实现旋转函数而不为每个可能的旋转声明一个? - 我需要很多这样的宏:-(
(不是这样:)
function rotate1...
function rotate2...
function rotate3...
...
最佳答案
您可以通过连接数据的两个副本并移位来模拟旋转:
function [31:0] rotate (input [31:0] data, input [4:0] shift);
reg [63:0] tmp;
begin
tmp = {data, data} >> shift;
rotate = tmp[31:0];
end
endfunction
关于function - 定义旋转长度不固定的 rightrotate 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6316653/