在 Verilog 中移位以进行乘法
Shifting in Verilog for multiplication
下面这行代码如何作为 (1024-31) 的乘法运算?
该代码旨在为 FPGA 综合,因此使用移位而不是直接除法。
但我不明白的是,这种移位如何模拟 reg_acc * (1024-31) 的值的乘法。
reg [27:0] reg_adj;
reg [27:0] reg_acc;
...
reg_adj <= ((reg_acc[11:0] << (20)) - ((reg_acc[11:0] << (15)) - (reg_acc[11:0] << (10)))) // x (1024-31)
...
记住 (n << k) = n * 2**k
(双 * 表示幂)
然后
(n << 20) - ((n << 15) - (n << 10)) =
(n * 2**20) - ((n*2**15) - (n*2**10)) =
(n * 2**10)*2**10 - ((n*2**5) - n)*2**10 =
2**10*(n*(2**10-(2**5-1)))
2**10 = 1024
、2**5=32
,所以表达式乘以 1024*(1024-(32-1))
,但结果几乎总是错误的,因为当你移出位时,它们将变为零,例如您正在将一个 12 位数移动 15 个位置。
我会简单地写 (reg_acc << 10) - ((reg_acc << 5) - reg_acc)
,
如果需要额外的 10
移位,您可以将整个表达式包装在另一个移位中。
下面这行代码如何作为 (1024-31) 的乘法运算?
该代码旨在为 FPGA 综合,因此使用移位而不是直接除法。
但我不明白的是,这种移位如何模拟 reg_acc * (1024-31) 的值的乘法。
reg [27:0] reg_adj;
reg [27:0] reg_acc;
...
reg_adj <= ((reg_acc[11:0] << (20)) - ((reg_acc[11:0] << (15)) - (reg_acc[11:0] << (10)))) // x (1024-31)
...
记住 (n << k) = n * 2**k
(双 * 表示幂)
然后
(n << 20) - ((n << 15) - (n << 10)) =
(n * 2**20) - ((n*2**15) - (n*2**10)) =
(n * 2**10)*2**10 - ((n*2**5) - n)*2**10 =
2**10*(n*(2**10-(2**5-1)))
2**10 = 1024
、2**5=32
,所以表达式乘以 1024*(1024-(32-1))
,但结果几乎总是错误的,因为当你移出位时,它们将变为零,例如您正在将一个 12 位数移动 15 个位置。
我会简单地写 (reg_acc << 10) - ((reg_acc << 5) - reg_acc)
,
如果需要额外的 10
移位,您可以将整个表达式包装在另一个移位中。