Verilog Barrel Shifter

Rob*_*ona 6 verilog rotation bit-shift shift case-statement

我想用verilog创建一个64位桶形移位器(现在向右旋转).我想知道是否有办法在不写65份案例陈述的情况下做到这一点?有没有办法写一些简单的代码,如:

    Y = {S[i - 1:0], S[63:i]};
Run Code Online (Sandbox Code Playgroud)

我在Xilinx中尝试了上面的代码并得到一个错误:我不是一个常数.

主要问题:如果没有庞大的案例陈述,有没有办法做到这一点?

小智 12

为了清晰起见,我简化了一些规则,但这里有详细信息.

在声明中

Y = {S[i - 1:0], S[63:i]};
Run Code Online (Sandbox Code Playgroud)

你有两个信号的串联,每个信号都有一个恒定的部分选择.常量部分选择是形式

标识符[constant_expression:constant_expression]

但是您的代码使用第一个表达式的变量.如您所见,这是不允许的,但您是正确的,因为有办法避免键入大型case语句.您可以使用的是索引部分选择.这些是形式

identifier [表达式+:constant_expression]

identifier [表达式 - :constant_expression]

无论左侧的变量如何,这些结构都强制生成的信号的宽度是恒定的.

wire [HIGH_BIT:LOW_BIT] signalAdd,signaSub;
signalAdd[some_expression +: some_range];
signalSub[some_expression -: some_range];
//Resolves to
signalAdd[some_expression + (some_range - 1) : some_expression];
signalSub[some_expression                    : some_expression - (some_range - 1)];

//The location of the high value depends on how the signal was declared:
wire [15: 0] a_vect;
wire [0 :15] b_vect;
a_vect[0 +: 8] // a_vect[7 : 0]
b_vect[0 +: 8] // b_vect[0 : 7]
Run Code Online (Sandbox Code Playgroud)

您可以简单地将输入信号扩展为128位,而不是尝试从两个部分选择中构建一个信号,并使用可变部分选择.

wire [63:0] data_in,data_out;
wire [127:0] data_in_double;
wire [5:0] select;

//Concatenate the input signal
assign data_in_double = {data_in,data_in};

//The same as signal[select + 63 : select]
assign data_out = data_in_double[select+63-:64];
Run Code Online (Sandbox Code Playgroud)

您可以使用的另一种方法是生成循环.这是一种基于变量复制代码的更通用方法.效率低得多,因为它产生了4096个信号.

wire [63:0] data_in,data_out;
wire [127:0] data_in_double;
wire [5:0] select;
wire [63:0] array [0:63];
genver i;

//Concatenate the input signal
assign data_in_double = {data_in,data_in};
for(i=0;i<64;i=i+1)
  begin : generate_loop
  //Allowed since i is constant when the loop is unrolled
  assign array[i] = data_in_double[63+i:i];
  /*
  Unrolls to 
  assign array[0] = data_in_double[63:0];
  assign array[1] = data_in_double[64:1];
  assign array[2] = data_in_double[65:2];
  ...
  assign array[63] = data_in_double[127:64];
  */
  end

//Select the shifted value
assign data_out = array[select];
Run Code Online (Sandbox Code Playgroud)