vivado DSP Block

本文介绍了如何在UltraScaleDSP块中使用预加器、乘法器和平方器进行动态配置,包括Verilog和VHDL代码示例,重点展示了如何在编码中优化计算,如用平方器代替绝对值差的计算。
摘要由CSDN通过智能技术生成

当对推理进行编码并以DSP块为目标时,建议使用签名算术运算,并且要求预加器结果有一个额外的宽度位,以便可以打包到DSP块中。

Pre-Adder Dynamically Configured Followed by
Multiplier and Post-Adder (Verilog)
Filename: dynpreaddmultadd.v
// Pre-add/subtract select with Dynamic control
// dynpreaddmultadd.v
module dynpreaddmultadd # (parameter SIZEIN = 16)
(
input clk, ce, rst, subadd,
input signed [SIZEIN-1:0] a, b, c, d,
output signed [2*SIZEIN:0] dynpreaddmultadd_out
);
// Declare registers for intermediate values
reg signed [SIZEIN-1:0] a_reg, b_reg, c_reg;
reg signed [SIZEIN:0] add_reg;
reg signed [2*SIZEIN:0] d_reg, m_reg, p_reg;
always @(posedge clk)
begin
if (rst)
begin
a_reg <= 0;
b_reg <= 0;
c_reg <= 0;
d_reg <= 0;
add_reg <= 0;
m_reg <= 0;
p_reg <= 0;
end
else if (ce)
begin
a_reg <= a;
b_reg <= b;
c_reg <= c;
d_reg <= d;
if (subadd)
add_reg <= a_reg - b_reg;
else
add_reg <= a_reg + b_reg;
m_reg <= add_reg * c_reg;
p_reg <= m_reg + d_reg;
end
end
// Output accumulation result
assign dynpreaddmultadd_out = p_reg;
endmodule // dynpreaddmultadd
Pre-Adder Dynamically Configured Followed by
Multiplier and Post-Adder (VHDL)
Filename: dynpreaddmultadd.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dynpreaddmultadd is
generic(
AWIDTH : natural := 12;
BWIDTH : natural := 16;
CWIDTH : natural := 17
);
port(
clk : in std_logic;
subadd : in std_logic;
ain : in std_logic_vector(AWIDTH - 1 downto 0);
bin : in std_logic_vector(BWIDTH - 1 downto 0);
cin : in std_logic_vector(CWIDTH - 1 downto 0);
din : in std_logic_vector(BWIDTH + CWIDTH downto 0);
pout : out std_logic_vector(BWIDTH + CWIDTH downto 0)
);
end dynpreaddmultadd;
architecture rtl of dynpreaddmultadd is
signal a : signed(AWIDTH - 1 downto 0);
signal b : signed(BWIDTH - 1 downto 0);
signal c : signed(CWIDTH - 1 downto 0);
signal add : signed(BWIDTH downto 0);
signal d, mult, p : signed(BWIDTH + CWIDTH downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
a <= signed(ain);
b <= signed(bin);
c <= signed(cin);
d <= signed(din);
if subadd = '1' then
add <= resize(a, BWIDTH + 1) - resize(b, BWIDTH + 1);
else
add <= resize(a, BWIDTH + 1) + resize(b, BWIDTH + 1);
end if;
mult <= add * c;
p <= mult + d;
end if;
end process;
--
-- Type conversion for output
--
pout <= std_logic_vector(p);
end rtl;

在UltraScale DSP块中使用平方器

UltraScale DSP块(DSP48E2)原语可以计算输入或输出的平方预加法器的。从编码示例下载编码示例文件。以下是差的平方的例子;这可以用来有效地替换差值绝对值的计算。它适用于单个DSP块,并以全速运行。提到的编码示例文件之前还包括一个差值平方的累加器,该累加器也适用于单个用于UltraScale体系结构的DSP块。

Square of a Difference (Verilog)
Filename: squarediffmult.v
// Squarer support for DSP block (DSP48E2) with
// pre-adder configured
// as subtractor
// File: squarediffmult.v
module squarediffmult # (parameter SIZEIN = 16)
(
input clk, ce, rst,
input signed [SIZEIN-1:0] a, b,
output signed [2*SIZEIN+1:0] square_out
);
// Declare registers for intermediate values
reg signed [SIZEIN-1:0] a_reg, b_reg;
reg signed [SIZEIN:0] diff_reg;
reg signed [2*SIZEIN+1:0] m_reg, p_reg;
always @(posedge clk)
begin
if (rst)
begin
a_reg <= 0;
b_reg <= 0;
diff_reg <= 0;
m_reg <= 0;
p_reg <= 0;
end
else
if (ce)
begin
a_reg <= a;
b_reg <= b;
diff_reg <= a_reg - b_reg;
m_reg <= diff_reg * diff_reg;
p_reg <= m_reg;
end
end
// Output result
assign square_out = p_reg;
endmodule // squarediffmult
Square of a Difference (VHDL)
Filename: squarediffmult.vhd
-- Squarer support for DSP block (DSP48E2) with pre-adder
-- configured
-- as subtractor
-- File: squarediffmult.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity squarediffmult is
generic(
SIZEIN : natural := 16
);
port(
clk, ce, rst : in std_logic;
ain, bin : in std_logic_vector(SIZEIN - 1 downto 0);
square_out : out std_logic_vector(2 * SIZEIN + 1 downto 0)
);
end squarediffmult;
architecture rtl of squarediffmult is
-- Declare intermediate values
signal a_reg, b_reg : signed(SIZEIN - 1 downto 0);
signal diff_reg : signed(SIZEIN downto 0);
signal m_reg, p_reg : signed(2 * SIZEIN + 1 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
a_reg <= (others => '0');
b_reg <= (others => '0');
diff_reg <= (others => '0');
m_reg <= (others => '0');
p_reg <= (others => '0');
else
a_reg <= signed(ain);
b_reg <= signed(bin);
diff_reg <= resize(a_reg, SIZEIN + 1) - resize(b_reg, SIZEIN + 1);
m_reg <= diff_reg * diff_reg;
p_reg <= m_reg;
end if;
end if;
end process;
--
-- Type conversion for output
--
square_out <= std_logic_vector(p_reg);
end rtl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cckkppll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值