function - 定义旋转长度不固定的 rightrotate 函数

标签 function parameters verilog

我需要 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/

相关文章:

javascript - 如何将小数简化为最小的分数?

C++ std::find() 在寻址返回 vector 的类函数时出现意外行为

verilog - 在 Verilog 中访问导线/规则尺寸

python - 艰苦学习Python练习20行号

javascript - 如何将对象属性作为参数传递? (JavaScript)

angularjs - $http 获取带有表单的请求

python - 在 Sphinx 中记录带有长描述的参数

concatenation - 使用串联符号扩展

verilog - Verilog 始终@* 敏感度列表中包含哪些内容?

PHP:变量在函数内部不起作用?