【Verilog HDL】如何正确地进行移位操作?逻辑移位、算数移位
为什么要移位操作
在FPGA中,数据的存储、逻辑运算、算数运算等都是以二进制的形式完成的,这就表明移位操作所需要的时间和占用的资源会非常少。
举例:
移位操作逼近常数乘除法
在FPGA中,常数乘法需要消耗乘法器,而移位操作只需要位宽截取和移动。所以对于常数乘法,我们一般转换为移位操作的组合来实现。
要实现 y = a ∗ 12 y=a*12 y=a∗12,我们可以转化为 y = a ∗ 8 + a ∗ 4 = a < < 3 + a < < 2 y=a*8+a*4=a<<3+a<<2 y=a∗8+a∗4=a<<3+a<<2。计算结果不变,实现资源大大减少了。
实现 y = a / 8 y=a/8 y=a/8,转化为 y = a > > 3 y=a>>3 y=a>>3
如何正确移位
在FPGA中,整数包含有符号数signed型和无符号数unsigned型。
无符号数
无符号数存储时就按照二进制存储。
比如 13 = 0 b 1101 13=0b1101 13=0b1101,存储时内存中就存储 1101 1101 1101。
有符号数
有符号数存储时按照该数字的补码形式存储。
我们不用管它补码是多少,只需要会取值,会用会移位就可以了。
逻辑移位
逻辑移位操作符号为<<和>>,逻辑移位不管如何移动,都是空位补零。
比如 8 ′ b 11110000 8'b11110000 8′b11110000左移两位,得到 8 ′ b 11000000 8'b11000000 8′b11000000,右移同理。
算数移位
算数移位操作符号为<<<和>>>,算数移位是为了解决有符号数进行逻辑移位后,数值大小不正常变化。
比如reg signed [7:0] r_a = -8,算数右移 r_a>>>2,r_a = -2。
也就是说,算数移位能保证只要数据不溢出,其数值变化永远符合移位算数逻辑。
移位算数逻辑意思是,不管是有符号数还是无符号数,左移能保证数值大小乘2,右移能保证数值大小除2并舍去小数。