这是VHDL代码,其中我使用DSP作为MACC单元(乘法累加)使用语言模板中可用的基元。在每7个时钟周期,我重置Preg,当我这样做时,该周期的乘法输出会丢失。如何在不丢失任何数据的情况下重置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;
答案 0 :(得分:0)
让我的评论回答。
根据您的描述,您似乎不想重置寄存器P.相反,您似乎希望累积每8个值。
如果您重置了注册表,您将始终获得您所看到的效果。相反,您希望动态地将DSP的操作模式更改为:
P_out = A*B (+0)
P_out = A*B+P_in
如Xilinx DSP48E1 user guide所示,您现在使用的OPMODE是"0100101"
,其中6-4位对您的目的很重要(表2-9)。 "010"
表示寄存器P的输出是后加法器的输入。您希望将其设置为"000"
,将输入设置为“零”(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;