如何将这个多项式乘法算法部署到verilog

问题描述 投票:0回答:1

我正在尝试将 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仿真的结果

this is the result of verilog simulation

this is the result of python simulation

This is the algorithm I use to multiply polynomials pic1

pic2

verilog
1个回答
0
投票

我对 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],您正在使用它,就像使用它一样。

© www.soinside.com 2019 - 2024. All rights reserved.