Verilog 枪管移位器 [英] Verilog Barrel Shifter

查看:21
本文介绍了Verilog 枪管移位器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create a 64-bit barrel shifter in verilog (rotate right for now). I want to know if there is a way to do it without writing a 65 part case statement? Is there a way to write some simple code such as:

    Y = {S[i - 1:0], S[63:i]};

我在 Xilinx 中尝试了上面的代码,得到一个错误:i is not a constant.

I tried the code above in Xilinx and get an error: i is not a constant.

主要问题:有没有办法在没有大量案例陈述的情况下做到这一点?

Main Question: Is there a way to do this without a huge case statment?

推荐答案

为了清楚起见,我已经简化了一些规则,但这里是细节.

I've simplified some of the rules for clarity, but here are the details.

在声明中

Y = {S[i - 1:0], S[63:i]};

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

you have a concatenation of two signals, each with a constant part select. A constant part select is of the form

标识符 [ constant_expression : constant_expression ]

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

but your code uses a variable for the first expression. As you saw this isn't allowed, but you are correct in that there are ways to avoid typing a large case statement. What you can use instead is an indexed part select. These are of the form

标识符 [ 表达式 +: 常量表达式 ]

标识符 [ 表达式 -: 常量表达式 ]

这些构造强制生成信号的宽度是恒定的,而不管左侧的变量如何.

These constructs enforce that the width of the resulting signal is constant, regardless of the variable on the left side.

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]

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

Rather than trying to build one signal out of two part selects, you can simply extend the input signal to 128 bits, and use a variable part select from that.

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];

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

Another approach you could use is generate loops. This is a more general approach to replicating code based on a variable. It is much less efficient since it creates 4096 signals.

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];

这篇关于Verilog 枪管移位器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆