定义旋转长度不固定的右旋功能

| 我需要在Verilog中为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的语法,我根本看不到指定参数的方法:
<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
    
        阿罗哈! 简单的解决方案是在输入的0-31步中使用固定旋转的MUX,然后使用x作为打开值。 为了实现高效,请看一下桶形移位器。使用五个2-1 32位MUX对输入进行16、8、4、2、1步(对于多路复用器0、1、2、3、4)的链式移位或不基于每个多路复用器的控制位进行移位。     

要回复问题请先登录注册