定义具有非固定旋转长度的rightrotate函数

时间:2011-06-11 15:10:28

标签: 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(...);

不适用于功能。事实上,通过阅读Verilog的grammar,我无法看到根本的方式来指定参数:

<function_call>
::= <name_of_function> ( <expression> <,<expression>>* )

我使用defparam的实验仅适用于模块,而不适用于函数。

由于Verilog中不存在参数化宏,我应该如何实现旋转函数而不为每个可能的旋转声明一个? - 我需要很多: - (

喜欢这样:):

function rotate1...
function rotate2...
function rotate3...
...

2 个答案:

答案 0 :(得分:5)

您可以通过连接两个数据副本并移动来模拟旋转:

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

答案 1 :(得分:0)

阿罗哈!

简单的解决方案是在输入的0-31步中使用固定旋转的MUX,然后使用x作为值来打开。

为了有效实施,请查看桶形移位器。根据每个多路复用器的控制位,使用5个2-1 32位多路复用器对输入进行16,8,4,2,1步(对于多路复用器0,1,2,3,4)进行链式移位。 / p>