我正在尝试将 GF(2m) 二进制多项式乘法代码从 python 代码迁移到 Verilog
ef bit_to_list(t, n):
#from int to binary list
S = [0 for i in range(n)]
i = -1
while t != 0:
S[i] = t % 2
t = t >> 1
i -= 1
return S
def list_to_bit(S):
"""
Converts the binary number in the list to an integer
Args:
S (list): A list of 0s and 1s, representing a binary number
Returns:
int: indicates the corresponding integer value
"""
n = len(S)
result = 0
for i in range(n):
result = (result << 1) + S[i]
return result
A=0x17a5b3f9ec1
B=0x71a3b6723027362b89d4ad344f678e139a023b693
C = [0 for _ in range(203)]
X=bit_to_list(A,41)
Y=bit_to_list(B,163)
for i in range(41):
for j in range(163):
C[i+j]=C[i+j]^(X[i]&Y[j])
print(hex(list_to_bit(C)))
但是,我按照下面的方式实现verilog代码后,modelsim仿真输出的结果是错误的,消耗的逻辑单元数量明显太少。我无法解决这个问题。希望您能给我一些帮助,我将不胜感激。
module multiplier_41x163_direct(
input clk,
input rst_n,
input [40:0] A,
input [162:0] B,
output [202:0] C);
reg [202:0] out_reg;
integer i,j;
assign C=out_reg;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin out_reg='b0; end
else begin
for(i=0;i<=40;i=i+1) begin
for(j=0;j<=162;j=j+1) begin
out_reg[i+j]=C[i+j]^(A[i]&B[j]);
end
end
end
end
endmodule
这是verilog仿真的结果
我对 Verilog 不太熟悉,但我想我至少可以指出这里的问题所在。
与 Verilog 相比,Python 中循环的工作方式有所不同。
这里引用来自NANDLAND:
“For 循环是新硬件开发人员难以解决的一个领域。您可能在 C 语言中见过数十次 for 循环,因此您认为它们在 Verilog 和 VHDL 中是相同的。在这里让我澄清一下:For 循环的行为并不相同硬件和软件的方式相同。
可综合代码中的 For 循环用于扩展复制逻辑。它们只是减少硬件设计人员编写的代码量的一种方法。”
这可能过于简单化,但你的循环是同时发生的。循环的每个分支同时运行,而不是顺序的。
所以这部分在Python中:
for i in range(41):
for j in range(163):
C[i+j]=C[i+j]^(X[i]&Y[j])
当 i=0 且 j=1 时,我们正在写入 c[1]。然后,当我们使用结果 c[1] 时,当我们达到 i=1 且 j=0 时,我们会重用该结果。通过这种方式,可以重用之前迭代的结果。
在你的verilog中,你只是以一种奇怪的方式将输入和输出连接在一起。当您编写
out_reg[i+j]=C[i+j]^(A[i]&B[j]);
时,您并没有重用之前迭代中的结果 C[i+j],您正在使用它,就像使用它一样。