我想在verilog中创建一个64位的桶形移位器(现在旋转)。我想知道是否有一种无需编写65个部分案例声明的方法?有没有办法编写一些简单的代码,例如:
Y = {S[i - 1:0], S[63:i]};
我在Xilinx中尝试了上面的代码,并得到一个错误:我不是一个常数。
主要问题:没有大量的案件陈述,有没有办法做到这一点?
最佳答案
为了简化起见,我简化了一些规则,但以下是详细信息。
在声明中
Y = {S[i - 1:0], S[63:i]};
您有两个信号的串联,每个信号都有恒定的部分选择。恒定零件选择的形式为
标识符[constant_expression:constant_expression]
但是您的代码在第一个表达式中使用了一个变量。如您所见,这是不允许的,但您的做法是正确的,因为有很多方法可以避免键入大写的语句。您可以使用的是索引零件选择。这些是形式
标识符[表达式+:constant_expression]
标识符[表达式-: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]
无需尝试从两个部分选择中构建一个信号,您只需将输入信号扩展到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];
您可以使用的另一种方法是生成循环。这是一种基于变量复制代码的更通用的方法。它会产生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];
关于rotation - Verilog桶式移位器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7543592/