在virtex 6 FPGA中重置Dsp切片的Preg

时间:2017-11-05 07:01:56

标签: vhdl signal-processing xilinx-ise

这是VHDL代码,其中我使用DSP作为MACC单元(乘法累加)使用语言模板中可用的基元。在每7个时钟周期,我重置Preg,当我这样做时,该周期的乘法输出会丢失。如何在不丢失任何数据的情况下重置Preg?

我附上了输出波形的截图。

output waveform

---------------------------------代码------------- --------------------------

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;

1 个答案:

答案 0 :(得分:0)

让我的评论回答。

根据您的描述,您似乎不想重置寄存器P.相反,您似乎希望累积每8个值。

如果您重置了注册表,您将始终获得您所看到的效果。相反,您希望动态地将DSP的操作模式更改为:

  • 乘法模式P_out = A*B (+0)
  • 的1个循环
  • MAC模式P_out = A*B+P_in
  • 的7个周期

Xilinx DSP48E1 user guide所示,您现在使用的OPMODE是"0100101",其中6-4位对您的目的很重要(表2-9)。 "010"表示寄存器P​​的输出是后加法器的输入。您希望将其设置为"000",将输入设置为“零”(0)。

因此,一个简单的解决方案是修改您的代码:

OPMODE => "0100101", 
RSTP =>Reset_p

要:

OPMODE => "0"&not(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;