Сброс Preg среза Dsp в virtex 6 FPGA

Вот код 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;

1 ответ

Решение

Давайте поместим мой комментарий в ответ.

Из вашего описания кажется, что вы не хотите сбрасывать регистр P. Вместо этого, кажется, вы хотите накапливать каждые 8 ​​значений.

Если вы сбросите регистр, вы всегда получите эффект, который видите. Вместо этого вы хотите динамически изменить режим работы DSP:

  • 1 цикл режима умножения P_out = A*B (+0)
  • 7 циклов режима MACP_out = A*B+P_in

Как показано в руководстве пользователя Xilinx DSP48E1, используемый вами 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;
Другие вопросы по тегам