Verilog 桶形移位器
我想用 verilog 创建一个 64 位桶形移位器(现在向右旋转)。我想知道是否有一种方法可以在不写 65 部分案例陈述的情况下做到这一点?有没有办法编写一些简单的代码,例如:
Y = {S[i - 1:0], S[63:i]};
我在 Xilinx 中尝试了上面的代码并得到一个错误:i 不是常量。
主要问题:有没有办法在没有大量案例陈述的情况下做到这一点?
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]};
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为了清楚起见,我简化了一些规则,但详细信息如下。
在该语句中,
您有两个信号的串联,每个信号都有一个常量部分选择。常量部分选择的形式为
标识符[constant_expression:constant_expression],
但您的代码使用第一个表达式的变量。正如您所看到的,这是不允许的,但您是正确的,因为有一些方法可以避免键入大的 case 语句。您可以使用索引零件选择来代替。它们的形式为
identifier [ expression +:constant_expression ]
identifier [ expression -:constant_expression ]
这些构造强制结果信号的宽度是恒定的,无论变量如何在左侧。
您无需尝试从两个部分选择中构建一个信号,只需将输入信号扩展至 128 位,然后使用其中的可变部分选择即可。
您可以使用的另一种方法是生成循环。这是基于变量复制代码的更通用方法。它的效率要低得多,因为它创建了 4096 个信号。
I've simplified some of the rules for clarity, but here are the details.
In the statement
you have a concatenation of two signals, each with a constant part select. A constant part select is of the form
identifier [ constant_expression : constant_expression ]
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
identifier [ expression +: constant_expression ]
identifier [ expression -: constant_expression ]
These constructs enforce that the width of the resulting signal is constant, regardless of the variable on the left side.
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.
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.
我发现做到这一点的最好方法是找到一种模式。当您想要向左旋转 8 位信号 1 个位置 (8'b00001111 << 1) 时,结果为 = 8'b00011110),当您想要向左旋转 9 个位置 (8'b00001111 << 9) 时,结果为 = 8'b00011110)结果是相同的 = 8'b00011110,并且还旋转 17 个位置,这会减少您进入下一个的可能性表:
所以如果你看一下,表上所有数字的树第一位相当于旋转 1 个位置 (1,9,17,25...249) 等于 001 (1)
表上所有数字的树第一位相当于旋转 6 个位置 (6,14,22,30...254) 等于 110 (6),
因此您可以应用掩码 (8'b00000111) 来确定正确的移位通过将所有其他位清零来计算数字:
reg_out_temp <= reg_in_1 << (reg_in_2 & 8'h07);
reg_out_temp 应是 reg_in_1 的双倍,在这种情况下 reg_out_temp 应是 16 位,reg_in_1 是 8 位,所以你当您移动数据时,可以将携带的位转移到另一个字节,以便您可以使用 OR 表达式将它们组合起来:
reg_out <= reg_out_temp[15:8] | reg_out_temp[7:0];
因此,通过两个时钟周期即可得到结果。对于 16 位旋转,您的掩码应为 8'b00011111 (8'h1F),因为您的移位从 0 到 16,并且您的临时寄存器应为 32 位。
The best way I found to do this is finding a pattern. When you want to rotate left an 8 bit signal 1 position (8'b00001111 << 1) the result is = 8'b00011110) also when you want to rotate left 9 positions (8'b00001111 << 9) the result is the same = 8'b00011110, and also rotating 17 positions, this reduce your possibilities to next table:
so if you look, the tree first bits of all numbers on table equivalent to rotate 1 position (1,9,17,25...249) are equal to 001 (1)
the tree first bits of all numbers on table equivalent to rotate 6 positions (6,14,22,30...254) are equal to 110 (6)
so you can apply a mask (8'b00000111) to determine the correct shifting number by making zero all other bits:
reg_out_temp <= reg_in_1 << (reg_in_2 & 8'h07);
reg_out_temp shall be the double of reg_in_1, in this case reg_out_temp shall be 16 bit and reg_in_1 8 bit, so you can get the carried bits to the other byte when you shift the data so you can combine them using an OR expression:
reg_out <= reg_out_temp[15:8] | reg_out_temp[7:0];
so by two clock cycles you have the result. For a 16 bit rotation, your mask shall be 8'b00011111 (8'h1F) because your shifts goes from 0 to 16, and your temporary register shall be of 32 bits.
我认为解决这个问题的最简单的方法是使用 {} 运算符复制输入单词,然后右移
I think the easiest solution to that problem is to replicate the input word using {} operator then shift right