在 Virtex 6 FPGA 中重置 Dsp 切片的 Preg
Resetting Preg of Dsp slice in virtex 6 FPGA
这是 VHDL 代码,其中我使用语言模板中可用的原语将 DSP 用作 MACC 单元(乘法累加)。在每第 7 个时钟周期,我重置 Preg,当我这样做时,该周期的乘法输出是 lost.How 我是否重置 Preg 而不会丢失任何数据?
附上输出波形截图。
--------------------------------代码------------ --------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dsp12 is
Port ( clk1 : in STD_LOGIC;
a_in1 : in STD_LOGIC_vector(29 downto 0);
b_in1 : in STD_LOGIC_vector(17 downto 0);
p_out : out STD_LOGIC_vector(47 downto 0);
reset_p: inout std_logic;
count :inout std_logic_vector(3 downto 0):="0000"
);
end dsp12;
architecture Behavioral of dsp12 is
signal reset: std_logic:='0';
begin
dsp1: DSP48E1
generic map(
-- Feature Control Attributes: Data Path Selection
A_INPUT => "DIRECT",
B_INPUT => "DIRECT",
USE_DPORT => FALSE,
USE_MULT => "MULTIPLY",
AUTORESET_PATDET => "NO_RESET",
MASK => X"ffffffffffff" ,
PATTERN => X"000000000000",
SEL_MASK => "MASK",
SEL_PATTERN => "PATTERN",
USE_PATTERN_DETECT => "NO_PATDET",
ACASCREG => 1,
ADREG => 0,
ALUMODEREG => 1,
AREG => 1,
BCASCREG => 1,
BREG => 1,
CARRYINREG => 1,
CARRYINSELREG => 1,
CREG =>0,
DREG => 0,
INMODEREG => 1,
MREG => 1,
OPMODEREG => 1,
PREG => 1,
USE_SIMD => "ONE48"
)
port map (
ACOUT =>open ,--ACOUT(i) ,
BCOUT =>open,--1,--BCOUT(i) ,
CARRYCASCOUT => open,
MULTSIGNOUT => open,
PCOUT => open ,
OVERFLOW => open,
PATTERNBDETECT => open,
PATTERNDETECT => open,
UNDERFLOW => open,
-- Data: 4-bit (each) Data Ports
CARRYOUT => open,
P => P_out,--P(i) ,
-- Cascade: 30-bit (each) Cascade Ports
ACIN =>"000000000000000000000000000000",
BCIN =>"000000000000000000",
CARRYCASCIN => '0',
MULTSIGNIN => '0',
PCIN => X"000000000000" ,
-- Control: 4-bit (each) Control Inputs/Status Bits
ALUMODE => "0000",
CARRYINSEL => "000",
CEINMODE => '0',
CLK => clk1,
INMODE => "00000",
OPMODE => "0100101",
RSTINMODE => '0',
-- Data: 30-bit (each) Data Ports
A => A_in1,
B => B_in1,
C => X"000000000000",
CARRYIN => '0',
D => "0000000000000000000000000",
-- Reset/Clock Enable: 1-bit (each) Reset/Clock Enable Inputs
CEA1 => '1',
CEA2 => '1',
CEAD =>'0',
CEALUMODE => '1',
CEB1 => '1',
CEB2 => '1',
CEC => '0',
CECARRYIN => '1',
CECTRL => '1',
CED =>'0' ,
CEM => '1',
CEP => '1',
RSTA => Reset,
RSTALLCARRYIN => Reset,
RSTALUMODE => Reset,
RSTB => Reset,
RSTC => Reset,
RSTCTRL => Reset,
RSTD =>Reset,
RSTM =>Reset,
RSTP =>Reset_p
);
process(clk1)
begin
if clk1' event and clk1='1' then
count<=count+"0001";
if count(2 downto 0)="111" then
reset_p<='1';
else reset_p<='0';
end if;
end if;
end process;
end Behavioral;
让我们把我的评论变成一个答案。
从你的描述来看,你似乎不想重置寄存器P。相反,你似乎想每8个值累加一次。
如果您重置寄存器,您将始终获得您所看到的效果。相反,您想将 DSP 的操作模式动态更改为:
- 乘法模式的 1 个周期
P_out = A*B (+0)
- MAC 模式的 7 个周期
P_out = A*B+P_in
如Xilinx DSP48E1 user guide所示,您现在使用的OPMODE是"0100101"
,其中第6-4位对您的目的很重要(table 2-9)。 "010"
表示寄存器 P 的输出是 post-加法器的输入。您想将其设置为 "000"
,将输入设置为 "zero"(0).
因此,一个简单的解决方案是修改您的代码:
OPMODE => "0100101",
RSTP =>Reset_p
收件人:
OPMODE => "0"¬(Reset_p)&"00101",
RSTP =>Reset
但你或许可以清理它。
不同的解决方案
除了将 DSP 实例化为组件,您还可以进行 RTL 描述。综合工具将理解这一点并生成您的 MAC。示例:这是一个 VHDL-2008 描述。会合成。
library ieee;
use ieee.std_logic_1164.all;
entity Accumulate8 is
port(
clk : in std_logic;
rst : in std_logic;
A : in std_logic_vector(29 downto 0);
B : in std_logic_vector(17 downto 0);
P : out std_logic_vector(47 downto 0)
);
end entity;
architecture rtl of Accumulate8 is
signal count : integer range 0 to 7 := 7;
use ieee.numeric_std.all;
begin
mac: process(clk)
begin
if rising_edge(clk) then
if count = 0 then
count <= 7;
P <= std_logic_vector(unsigned(A)*unsigned(B));
else
count <= count - 1;
P <= std_logic_vector(unsigned(A)*unsigned(B)+unsigned(P));
end if;
if rst = '1' then
count <= 7;
P <= (others => '0');
end if;
end if;
end process;
end architecture;
测试台
entity Accumulate8_tb is end entity;
library ieee;
architecture rtl of Accumulate8_tb is
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
signal clk : std_logic;
signal rst : std_logic;
signal A : unsigned(29 downto 0) := (others => '0');
signal B : unsigned(17 downto 0) := (others => '0');
signal P : std_logic_vector(47 downto 0);
begin
clk_proc: process begin
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end process;
rst_proc: process begin
rst <= '1';
wait for 4 ns;
rst <= '0';
wait;
end process;
cnt_proc : process(clk) begin
if rising_edge(clk) then
A <= A + 3;
B <= B + 7;
end if;
end process;
DUT: entity work.Accumulate8
port map(
clk => clk,
rst => rst,
A => std_logic_vector(A),
B => std_logic_vector(B),
P => P
);
end architecture;
这是 VHDL 代码,其中我使用语言模板中可用的原语将 DSP 用作 MACC 单元(乘法累加)。在每第 7 个时钟周期,我重置 Preg,当我这样做时,该周期的乘法输出是 lost.How 我是否重置 Preg 而不会丢失任何数据?
附上输出波形截图。
--------------------------------代码------------ --------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dsp12 is
Port ( clk1 : in STD_LOGIC;
a_in1 : in STD_LOGIC_vector(29 downto 0);
b_in1 : in STD_LOGIC_vector(17 downto 0);
p_out : out STD_LOGIC_vector(47 downto 0);
reset_p: inout std_logic;
count :inout std_logic_vector(3 downto 0):="0000"
);
end dsp12;
architecture Behavioral of dsp12 is
signal reset: std_logic:='0';
begin
dsp1: DSP48E1
generic map(
-- Feature Control Attributes: Data Path Selection
A_INPUT => "DIRECT",
B_INPUT => "DIRECT",
USE_DPORT => FALSE,
USE_MULT => "MULTIPLY",
AUTORESET_PATDET => "NO_RESET",
MASK => X"ffffffffffff" ,
PATTERN => X"000000000000",
SEL_MASK => "MASK",
SEL_PATTERN => "PATTERN",
USE_PATTERN_DETECT => "NO_PATDET",
ACASCREG => 1,
ADREG => 0,
ALUMODEREG => 1,
AREG => 1,
BCASCREG => 1,
BREG => 1,
CARRYINREG => 1,
CARRYINSELREG => 1,
CREG =>0,
DREG => 0,
INMODEREG => 1,
MREG => 1,
OPMODEREG => 1,
PREG => 1,
USE_SIMD => "ONE48"
)
port map (
ACOUT =>open ,--ACOUT(i) ,
BCOUT =>open,--1,--BCOUT(i) ,
CARRYCASCOUT => open,
MULTSIGNOUT => open,
PCOUT => open ,
OVERFLOW => open,
PATTERNBDETECT => open,
PATTERNDETECT => open,
UNDERFLOW => open,
-- Data: 4-bit (each) Data Ports
CARRYOUT => open,
P => P_out,--P(i) ,
-- Cascade: 30-bit (each) Cascade Ports
ACIN =>"000000000000000000000000000000",
BCIN =>"000000000000000000",
CARRYCASCIN => '0',
MULTSIGNIN => '0',
PCIN => X"000000000000" ,
-- Control: 4-bit (each) Control Inputs/Status Bits
ALUMODE => "0000",
CARRYINSEL => "000",
CEINMODE => '0',
CLK => clk1,
INMODE => "00000",
OPMODE => "0100101",
RSTINMODE => '0',
-- Data: 30-bit (each) Data Ports
A => A_in1,
B => B_in1,
C => X"000000000000",
CARRYIN => '0',
D => "0000000000000000000000000",
-- Reset/Clock Enable: 1-bit (each) Reset/Clock Enable Inputs
CEA1 => '1',
CEA2 => '1',
CEAD =>'0',
CEALUMODE => '1',
CEB1 => '1',
CEB2 => '1',
CEC => '0',
CECARRYIN => '1',
CECTRL => '1',
CED =>'0' ,
CEM => '1',
CEP => '1',
RSTA => Reset,
RSTALLCARRYIN => Reset,
RSTALUMODE => Reset,
RSTB => Reset,
RSTC => Reset,
RSTCTRL => Reset,
RSTD =>Reset,
RSTM =>Reset,
RSTP =>Reset_p
);
process(clk1)
begin
if clk1' event and clk1='1' then
count<=count+"0001";
if count(2 downto 0)="111" then
reset_p<='1';
else reset_p<='0';
end if;
end if;
end process;
end Behavioral;
让我们把我的评论变成一个答案。
从你的描述来看,你似乎不想重置寄存器P。相反,你似乎想每8个值累加一次。
如果您重置寄存器,您将始终获得您所看到的效果。相反,您想将 DSP 的操作模式动态更改为:
- 乘法模式的 1 个周期
P_out = A*B (+0)
- MAC 模式的 7 个周期
P_out = A*B+P_in
如Xilinx DSP48E1 user guide所示,您现在使用的OPMODE是"0100101"
,其中第6-4位对您的目的很重要(table 2-9)。 "010"
表示寄存器 P 的输出是 post-加法器的输入。您想将其设置为 "000"
,将输入设置为 "zero"(0).
因此,一个简单的解决方案是修改您的代码:
OPMODE => "0100101",
RSTP =>Reset_p
收件人:
OPMODE => "0"¬(Reset_p)&"00101",
RSTP =>Reset
但你或许可以清理它。
不同的解决方案
除了将 DSP 实例化为组件,您还可以进行 RTL 描述。综合工具将理解这一点并生成您的 MAC。示例:这是一个 VHDL-2008 描述。会合成。
library ieee;
use ieee.std_logic_1164.all;
entity Accumulate8 is
port(
clk : in std_logic;
rst : in std_logic;
A : in std_logic_vector(29 downto 0);
B : in std_logic_vector(17 downto 0);
P : out std_logic_vector(47 downto 0)
);
end entity;
architecture rtl of Accumulate8 is
signal count : integer range 0 to 7 := 7;
use ieee.numeric_std.all;
begin
mac: process(clk)
begin
if rising_edge(clk) then
if count = 0 then
count <= 7;
P <= std_logic_vector(unsigned(A)*unsigned(B));
else
count <= count - 1;
P <= std_logic_vector(unsigned(A)*unsigned(B)+unsigned(P));
end if;
if rst = '1' then
count <= 7;
P <= (others => '0');
end if;
end if;
end process;
end architecture;
测试台
entity Accumulate8_tb is end entity;
library ieee;
architecture rtl of Accumulate8_tb is
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
signal clk : std_logic;
signal rst : std_logic;
signal A : unsigned(29 downto 0) := (others => '0');
signal B : unsigned(17 downto 0) := (others => '0');
signal P : std_logic_vector(47 downto 0);
begin
clk_proc: process begin
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end process;
rst_proc: process begin
rst <= '1';
wait for 4 ns;
rst <= '0';
wait;
end process;
cnt_proc : process(clk) begin
if rising_edge(clk) then
A <= A + 3;
B <= B + 7;
end if;
end process;
DUT: entity work.Accumulate8
port map(
clk => clk,
rst => rst,
A => std_logic_vector(A),
B => std_logic_vector(B),
P => P
);
end architecture;