在 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 = 10242**5=32,所以表达式乘以 1024*(1024-(32-1)),但结果几乎总是错误的,因为当你移出位时,它们将变为零,例如您正在将一个 12 位数移动 15 个位置。

我会简单地写 (reg_acc << 10) - ((reg_acc << 5) - reg_acc), 如果需要额外的 10 移位,您可以将整个表达式包装在另一个移位中。