Cryptography 如何使用非常有限的资源将两个1024位无符号整数相乘(BASYS 2)
我将通过串行通信获取两个1024位无符号整数(8位乘以8位),将ASCII转换为二进制,然后将它们相乘,形成2048位的输出。主要问题是我必须用一块面积非常小的FPGA板(BASYS2)进行乘法运算 乘法速度对我来说不是一个重要的标准,我可以等待相当长的时间(约1秒)来获得正确的乘法结果。 以下是我的FPGA的资源信息: 什么是一种简单有效的方法?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位到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位的加法器只占我面积使用量的大约%53sum
和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;