vivado Multipliers

Vivado synthesis从源代码中的乘法运算符推断乘法器宏。这个得到的信号宽度等于两个操作数大小之和。例如,乘以16位信号乘以8比特信号产生24比特的结果。

建议:如果您不打算使用设备的所有最高有效位,AMD建议将操作数的大小减小到所需的最小值,尤其是在实现了“倍增”宏的情况下片上逻辑。

乘法器实现

乘法器宏可以实现在:

•切片逻辑

•DSP块

实施选择是:

•受操作数大小的驱动

•旨在最大限度地提高性能

要强制将乘法器实现为切片逻辑或DSP块,请将USE_DSP属性设置为适当的信号、实体或模块:

•否(切片逻辑)

•是(DSP块)

DSP块实现

当在单个DSP块中实现乘法器时,Vivado合成试图利用这一优势DSP块的流水线能力。Vivado合成最多可提取两级寄存器present:在乘法运算数上,以及在乘法运算之后。当乘法器不适合单个DSP块时,Vivado合成将宏分解为实现它。在这种情况下,Vivado合成使用以下任一项:

•几个DSP块

•涉及DSP块和片逻辑的混合解决方案

使用KEEP属性限制寄存器吸收到DSP块中。例如,如果寄存器存在于乘法器的操作数上,请将KEEP放在寄存器的输出上以防止寄存器被吸收到DSP块中。

Multipliers Coding Examples
Unsigned 16x24-Bit Multiplier Coding Verilog Example
Filename: mult_unsigned.v
// Unsigned 16x24-bit Multiplier
// 1 latency stage on operands
// 3 latency stage after the multiplication
// File: multipliers2.v
//
module mult_unsigned (clk, A, B, RES);
parameter WIDTHA = 16;
parameter WIDTHB = 24;
input clk;
input [WIDTHA-1:0] A;
input [WIDTHB-1:0] B;
output [WIDTHA+WIDTHB-1:0] RES;
reg [WIDTHA-1:0] rA;
reg [WIDTHB-1:0] rB;
reg [WIDTHA+WIDTHB-1:0] M [3:0];
integer i;
always @(posedge clk)
begin
rA <= A;
rB <= B;
M[0] <= rA * rB;
for (i = 0; i < 3; i = i+1)
M[i+1] <= M[i];
end
assign RES = M[3];
endmodule
Unsigned 16x16-Bit Multiplier Coding VHDL Example
Filename: mult_unsigned.vhd
-- Unsigned 16x16-bit Multiplier
-- File: mult_unsigned.vhd
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mult_unsigned is
generic(
WIDTHA : integer := 16;
WIDTHB : integer := 16
);
port(
A : in std_logic_vector(WIDTHA - 1 downto 0);
B : in std_logic_vector(WIDTHB - 1 downto 0);
RES : out std_logic_vector(WIDTHA + WIDTHB - 1 downto 0)
);
end mult_unsigned;
architecture beh of mult_unsigned is
begin
RES <= A * B;
end beh;

乘法加法和乘法累加

推断出以下宏:

•乘加

•乘子

•乘法加法/减法

•乘法累加

宏是通过以下各项的聚合来推断的:

•乘数

•加法器/减法器

•寄存器

乘法加法和乘法累加的实现

在乘法-加法和乘法-累加实现过程中:

•Vivado合成可以在上实现推断的乘法-加法或乘法-累加宏DSP块资源。

•Vivado synthesis试图利用DSP块的流水线功能。

•Vivado合成达到:

○ 乘法运算数上存在两个寄存器级。

○ 乘法运算后出现的一个寄存器级。

○ 在加法器、减法器或加法器/减法器之后找到一个寄存器阶段。

○ 添加/子选择信号上的一个寄存器级。

○ 加法器上的一个寄存器级可选进位输入。

•Vivado合成可以在DSP块中实现乘法累加,如果实现的话仅需要单个DSP资源。

•如果宏超过单个DSP的限制,Vivado合成会执行以下操作:

○ 将其处理为两个独立的“倍增”和“累加”宏。

○ 对每个宏进行独立决策。

DSP块资源的宏实现

Vivado合成中默认推断DSP块资源上的宏实现。

•在默认模式下,Vivado合成:

○ 实现乘法-加法和乘法-累加宏。

○ 考虑目标设备中DSP块资源的可用性。

○ 使用所有可用的DSP资源。

○ 试图通过利用的所有流水线功能来最大限度地提高电路性能DSP块。

○ 扫描将寄存器吸收到乘法加法或乘法累加中的机会宏。

使用KEEP属性限制寄存器吸收到DSP块中。例如,到排除乘法器的操作数上存在的寄存器吸收到DSP块中,对寄存器的输出应用KEEP。有关KEEP属性的详细信息,请参见保持。

复杂乘法器示例

以下示例显示VHDL和Verilog中的复杂乘法器示例。编码示例文件还包括一个使用三个DSP的带累加的复数乘法器示例AMD UltraScale™体系结构的块。

复杂乘法器Verilog示例

使用三个DSP块的全流水线复数乘法器。

Filename: cmult.v
//
// Complex Multiplier (pr+i.pi) = (ar+i.ai)*(br+i.bi)
// file: cmult.v
module cmult # (parameter AWIDTH = 16, BWIDTH = 18)
(
input clk,
input signed [AWIDTH-1:0] ar, ai,
input signed [BWIDTH-1:0] br, bi,
output signed [AWIDTH+BWIDTH:0] pr, pi
);
reg signed [AWIDTH-1:0] ai_d, ai_dd, ai_ddd, ai_dddd ;
reg signed [AWIDTH-1:0] ar_d, ar_dd, ar_ddd, ar_dddd ;
reg signed [BWIDTH-1:0] bi_d, bi_dd, bi_ddd, br_d, br_dd, br_ddd ;
reg signed [AWIDTH:0] addcommon ;
reg signed [BWIDTH:0] addr, addi ;
reg signed [AWIDTH+BWIDTH:0] mult0, multr, multi, pr_int, pi_int ;
reg signed [AWIDTH+BWIDTH:0] common, commonr1, commonr2 ;
always @(posedge clk)
begin
ar_d <= ar;
ar_dd <= ar_d;
ai_d <= ai;
ai_dd <= ai_d;
br_d <= br;
br_dd <= br_d;
br_ddd <= br_dd;
bi_d <= bi;
bi_dd <= bi_d;
bi_ddd <= bi_dd;
end
// Common factor (ar ai) x bi, shared for the calculations of the real and
imaginary final products
//
always @(posedge clk)
begin
addcommon <= ar_d - ai_d;
mult0 <= addcommon * bi_dd;
common <= mult0;
end
// Real product
//
always @(posedge clk)
begin
ar_ddd <= ar_dd;
ar_dddd <= ar_ddd;
addr <= br_ddd - bi_ddd;
multr <= addr * ar_dddd;
commonr1 <= common;
pr_int <= multr + commonr1;
end
// Imaginary product
//
always @(posedge clk)
begin
ai_ddd <= ai_dd;
ai_dddd <= ai_ddd;
addi <= br_ddd + bi_ddd;
multi <= addi * ai_dddd;
commonr2 <= common;
pi_int <= multi + commonr2;
end
assign pr = pr_int;
assign pi = pi_int;
endmodule // cmult
Complex Multiplier Examples (VHDL)
Fully pipelined complex multiplier using three DSP blocks.
Filename: cmult.vhd
-- Complex Multiplier (pr+i.pi) = (ar+i.ai)*(br+i.bi)
--
--
-- cumult.vhd
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity cmult is
generic(AWIDTH : natural := 16;
BWIDTH : natural := 16);
port(clk : in std_logic;
ar, ai : in std_logic_vector(AWIDTH - 1 downto 0);
br, bi : in std_logic_vector(BWIDTH - 1 downto 0);
pr, pi : out std_logic_vector(AWIDTH + BWIDTH downto 0));
end cmult;
architecture rtl of cmult is
signal ai_d, ai_dd, ai_ddd, ai_dddd : signed(AWIDTH - 1 downto 0);
signal ar_d, ar_dd, ar_ddd, ar_dddd : signed(AWIDTH - 1 downto 0);
signal bi_d, bi_dd, bi_ddd, br_d, br_dd, br_ddd : signed(BWIDTH - 1 downto
0);
signal addcommon : signed(AWIDTH downto 0);
signal addr, addi : signed(BWIDTH downto 0);
signal mult0, multr, multi, pr_int, pi_int : signed(AWIDTH + BWIDTH downto
0);
signal common, commonr1, commonr2 : signed(AWIDTH + BWIDTH downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
ar_d <= signed(ar);
ar_dd <= signed(ar_d);
ai_d <= signed(ai);
ai_dd <= signed(ai_d);
br_d <= signed(br);
br_dd <= signed(br_d);
br_ddd <= signed(br_dd);
bi_d <= signed(bi);
bi_dd <= signed(bi_d);
bi_ddd <= signed(bi_dd);
end if;
end process;
-- Common factor (ar - ai) x bi, shared for the calculations
-- of the real and imaginary final products.
--
process(clk)
begin
if rising_edge(clk) then
addcommon <= resize(ar_d, AWIDTH + 1) - resize(ai_d, AWIDTH + 1);
mult0 <= addcommon * bi_dd;
common <= mult0;
end if;
end process;
-- Real product
--
process(clk)
begin
if rising_edge(clk) then
ar_ddd <= ar_dd;
ar_dddd <= ar_ddd;
addr <= resize(br_ddd, BWIDTH + 1) - resize(bi_ddd, BWIDTH + 1);
multr <= addr * ar_dddd;
commonr1 <= common;
pr_int <= multr + commonr1;
end if;
end process;
-- Imaginary product
--
process(clk)
begin
if rising_edge(clk) then
ai_ddd <= ai_dd;
ai_dddd <= ai_ddd;
addi <= resize(br_ddd, BWIDTH + 1) + resize(bi_ddd, BWIDTH + 1);
multi <= addi * ai_dddd;
commonr2 <= common;
pi_int <= multi + commonr2;
end if;
end process;
--
-- VHDL type conversion for output
--
pr <= std_logic_vector(pr_int);
pi <= std_logic_vector(pi_int);
end rtl;

你可能感兴趣的:(fpga开发)