旋转左侧verilog案例

时间:2014-01-17 17:17:59

标签: rotation verilog shift

我的任务是在verilog中写一个16位的ALU。当我做需要旋转操作数并执行2的补码加法和减法的部分时,我发现了困难。我知道如何通过纸和笔来解决这个问题,但我无法弄清楚如何在Verilog中做到这一点。 例如: A表示为a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 如果我要旋转4位, 答案是 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 a15 a14 a13 a12

我尝试连接,但结果证明是不正确的。 需要你们的帮助...

4 个答案:

答案 0 :(得分:4)

以下将使用一个移位器:

assign A_out = {A_in,A_in} >> (16-shift[3:0]);

shift为0时,左侧A_in被选中。当shift向左移动A_in时向右移动,右A_in的MSB填充。

如果要合成,那么您可能想要使用多路复用器,因为动态移位逻辑往往需要更多的门。 16位barrel shifter需要4级2对1多路复用器。

wire [15:0] tmp [3:1];
assign tmp[3] = shift[3] ? {  A_in[ 7:0],  A_in[15: 8]} : A_in;
assign tmp[2] = shift[2] ? {tmp[3][11:0],tmp[3][15:12]} : tmp[3];
assign tmp[1] = shift[1] ? {tmp[2][13:0],tmp[2][15:14]} : tmp[2];
assign A_out  = shift[0] ? {tmp[1][14:0],tmp[1][15   ]} : tmp[1];

答案 1 :(得分:2)

为什么连接不正确?这应该按照你的要求做。

 assign A_out[15:0] = {A_in[11:0], A_in[15:12]};

答案 2 :(得分:2)

assign A_out = A_in << bits_to_rotate;

bits_to_rotate可以是变量值(信号或reg)。 这将推断使用多路复用器或桶形移位器的通用移位器,无论哪种更适合目标硬件。合成器会照顾它。


哦,好吧。如果你想旋转而不是转移,那么事情就有点棘手了:

assign A_out = (A_in << bits_to_rotate) | (A_in >> ~bits_to_rotate);

答案 3 :(得分:0)

我发现这样做的最好方法是找到一种模式。如果要向左旋转8位信号1位置(8'b00001111 << 1),结果为8'b00011110),当您想要向左旋转9个位置(8'b00001111 << 9)时,结果是相同的, 8'b00011110,还有17个位置,这减少了你进入下一个桌面的可能性:

PATTERN_TABLE

所以如果你看一下,故事中所有数字的三个第一位相当于旋转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位且{{1} 8位,所以你可以在移位数据时将携带的位移到另一个字节,这样你就可以使用OR表达式将它们组合起来:

reg_in_1

因此,通过两个时钟周期,您将获得结果。对于16位旋转,您的掩码应为reg_out <= reg_out_temp[15:8] | reg_out_temp[7:0]; 8'b00011111),因为您的移位从0到16,而您的临时寄存器应为32位。