Cryptography 如何使用非常有限的资源将两个1024位无符号整数相乘(BASYS 2)

Cryptography 如何使用非常有限的资源将两个1024位无符号整数相乘(BASYS 2),cryptography,vhdl,verilog,fpga,Cryptography,Vhdl,Verilog,Fpga,我将通过串行通信获取两个1024位无符号整数(8位乘以8位),将ASCII转换为二进制,然后将它们相乘,形成2048位的输出。主要问题是我必须用一块面积非常小的FPGA板(BASYS2)进行乘法运算 乘法速度对我来说不是一个重要的标准,我可以等待相当长的时间(约1秒)来获得正确的乘法结果。 以下是我的FPGA的资源信息: 什么是一种简单有效的方法? 一个1024位到1024位的加法器仅占我使用面积的大约%53 我假设您确信确实需要一个真正的1024 x 1024乘法器(在许多应用中,便宜得多的

我将通过串行通信获取两个1024位无符号整数(8位乘以8位),将ASCII转换为二进制,然后将它们相乘,形成2048位的输出。主要问题是我必须用一块面积非常小的FPGA板(BASYS2)进行乘法运算

乘法速度对我来说不是一个重要的标准,我可以等待相当长的时间(约1秒)来获得正确的乘法结果。 以下是我的FPGA的资源信息:

什么是一种简单有效的方法?
一个1024位到1024位的加法器仅占我使用面积的大约%53

我假设您确信确实需要一个真正的1024 x 1024乘法器(在许多应用中,便宜得多的东西就足够了)。也许这是显而易见的,但作为一个起点,我会尝试一个非常简单的shift-add。类似的方法会奏效(我相信您可以进一步优化它以满足您的需求):

ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体范围的\u mult是
一般的(
A_位:正:=1024;
B_位:正:=1024
);
港口(
clk:标准逻辑中;
--输入
in_valid:标准_逻辑中;
in_a:在无符号中(a_位-1降到0);
in_b:在无符号中(b_位-1降到0);
--输出
out\u有效:out std\u逻辑;
out_prod:out unsigned(A_位+B_位-1到0)
);
端宽多头;
广域网的rtl体系结构
信号移位_a:无符号(a_位-1向下至0);
信号移位b:无符号(A_位+b_位-1向下至0);
信号进程:标准逻辑向量(A位-1降到0);
信号和:无符号(A_位+B_位-1到0);
开始
过程(clk)
开始
如果上升沿(clk),则
--周期1
如果in_valid='1',则
--初始化

我想你肯定真的需要一个真正的1024x1024乘法器(在许多应用中,便宜得多的东西就足够了)。也许这是显而易见的,但作为一个起点,我会尝试一个非常简单的shift-add。类似的方法会奏效(我相信您可以进一步优化它以满足您的需求):

ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体范围的\u mult是
一般的(
A_位:正:=1024;
B_位:正:=1024
);
港口(
clk:标准逻辑中;
--输入
in_valid:标准_逻辑中;
in_a:在无符号中(a_位-1降到0);
in_b:在无符号中(b_位-1降到0);
--输出
out\u有效:out std\u逻辑;
out_prod:out unsigned(A_位+B_位-1到0)
);
端宽多头;
广域网的rtl体系结构
信号移位_a:无符号(a_位-1向下至0);
信号移位b:无符号(A_位+b_位-1向下至0);
信号进程:标准逻辑向量(A位-1降到0);
信号和:无符号(A_位+B_位-1到0);
开始
过程(clk)
开始
如果上升沿(clk),则
--周期1
如果in_valid='1',则
--初始化

请看。你能问一个具体的编程问题吗?什么是一种简单有效的方法?不是特定的编程问题。有关1024个步骤,请参见.Shift和有条件地添加。一位移位需要多少空间?计算1024步需要多少空间?@user1155120:你跳了枪。他没有问过模乘。保持粉末干燥,这几乎肯定是他的下一个问题;)您能为您的1024位加法器显示切片、LUT和FFs的使用情况吗?串行二进制加法器可以减少使用。请参阅。你能问一个具体的编程问题吗?什么是一种简单有效的方法?不是特定的编程问题。有关1024个步骤,请参见.Shift和有条件地添加。一位移位需要多少空间?计算1024步需要多少空间?@user1155120:你跳了枪。他没有问过模乘。保持粉末干燥,这几乎肯定是他的下一个问题;)您能为您的1024位加法器显示切片、LUT和FFs的使用情况吗?串行二进制加法器可以减少使用量。一个1024位到1024位的加法器只占我面积使用量的大约%53
sum
shifted_b
是长度
A_位+b_位
(2048),其中
sum我想我是在您仍在写此评论时编辑以删除信号
A
。我回答的“改变你的方法”部分涵盖了你的“保证不适合”评论。也许令人惊讶的是,计数器不一定会降低FPGA利用率。在我最近使用的一个设备中(针对一个非常类似的问题),试验实施表明计数器只会在计数超过数千次时降低利用率!当然,这最终将取决于所使用的设备(因此我的答案中的“您可以进一步优化它以满足您的需求”部分)。谢谢Harry,尽管我已经习惯了用Verilog编写。我检查了你的代码,它消耗了256位x256位的片的%102。在这个阶段,我将乘法目标缩小到256位。您的代码似乎非常适合我的FPGA。有没有想法用加法器设计一个低面积?@utdlegend我从来没有想过这个。是的,如果我们能用一个更便宜的多周期加法器来代替加法器,那么你肯定能使它适合。我会考虑的。也许这里的其他人知道一个好的解决方案。我还没有尝试过,但我认为如果您一次完成所有8x8位,它应该很容易适应。但是确保所有中间编号均以BRAM格式读取和写回。更多的定时编码,但不浪费大量的寄存器。我写Verilog,我可能只是为了好玩而尝试一下。1024位
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity wide_mult is
generic (
    A_BITS          : positive := 1024;
    B_BITS          : positive := 1024
);
port (
    clk             : in std_logic;
    -- Input
    in_valid        : in std_logic;
    in_a            : in unsigned(A_BITS-1 downto 0);
    in_b            : in unsigned(B_BITS-1 downto 0);
    -- Output
    out_valid       : out std_logic;
    out_prod        : out unsigned(A_BITS+B_BITS-1 downto 0)
);
end wide_mult;

architecture rtl of wide_mult is

    signal shifted_a    : unsigned(A_BITS-1 downto 0);
    signal shifted_b    : unsigned(A_BITS+B_BITS-1 downto 0);
    signal progress     : std_logic_vector(A_BITS-1 downto 0);

    signal sum          : unsigned(A_BITS+B_BITS-1 downto 0);

begin

    process(clk)
    begin
        if rising_edge(clk) then
            -- Cycle 1
            if in_valid = '1' then
                -- Initialize
                shifted_a <= in_a;
                shifted_b <= resize(in_b, A_BITS+B_BITS);
                progress <= std_logic_vector(to_unsigned(1, A_BITS));
            else
                -- Shift
                shifted_a <= shift_right(shifted_a, 1);
                shifted_b <= shift_left(shifted_b, 1);
                progress <= progress(A_BITS-2 downto 0) & '0';
            end if;

            -- Cycle 2 - Accumulate sum
            out_valid <= progress(A_BITS-1);
            if progress(0) = '1' then
                -- Init sum
                if shifted_a(0) = '0' then
                    sum <= (others => '0');
                else
                    sum <= shifted_b;
                end if;
            elsif shifted_a(0) = '1' then
                -- Accumulate
                sum <= sum + shifted_b;
            end if;
        end if;
    end process;
    out_prod <= sum;

end rtl;