реклама на сайте
подробности

 
 
> Pipelined MAC, You can improve the performance of the multiplier by adding 2 register
count_enable
сообщение Jan 26 2015, 12:22
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 310
Регистрация: 28-01-13
Из: Лондон
Пользователь №: 75 384



Делаю простенькое ALU на операции типа О=О+(А*В), О=С+(А*В) которое должно синтезироваться в Xilinxoвый DSP48. Код довольно стандартный, входящие сигналы и выходящий имеют по регистру. Синтезатор мне пишет: "Xst:2385 - HDL ADVISOR - You can improve the performance of the multiplier alu_module/Mmult_i_result_mult0000 by adding 2 register level(s)." Ну и скорость удручающая.. Где именно надо пихнуть эти регистры? А - это вход от BRAM, C-результат от предыдущего DSP48 блока, поэтому важна синхронная скорость BRAM и DSP48. Насколько я знаю, Xilinx специально делает эти блоки максимально совместимыми.

Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity ALU is
generic(
        MIN:integer:=-255; -- не всегда совпадает с 2**DATA_WIDTH
        MAX:integer:=255;
        DATA_WIDTH:integer:=9
        );
    Port ( RST : in  STD_LOGIC;
           CLK : in  STD_LOGIC;
           A : in  STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
           B : in  STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
           C : in  STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
           R : out  STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
           OPCODE : in  STD_LOGIC_VECTOR (2 downto 0));
end ALU;

architecture Behavioral of ALU is
signal i_result,i_rmul:  signed(DATA_WIDTH*2-1 downto 0);
signal i_A,i_B,i_C: STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
begin
process (CLK,RST)
begin
if RST='1' then
        i_result<=(others=>'0');
        i_rmul<=(others=>'0');
        i_A<=(others=>'0');
    i_B<=(others=>'0');
    i_C<=(others=>'0');
else
    if (rising_edge(CLK)) then
    i_A<=A;
    i_B<=B;
    i_C<=C;
        case OPCODE is
            when "000" => --- R=0
                                i_result<=to_signed(0,DATA_WIDTH*2);    
                                i_rmul<=to_signed(0,DATA_WIDTH*2);                                    
            when "001" => --- R=R+(A*B)
                                i_rmul<=(signed(i_A)*signed(i_B));
                                i_result<=resize(i_result+i_rmul,DATA_WIDTH*2);
            when "010" => --- R=C+(A*B)
                                i_rmul<=(signed(i_A)*signed(i_B));
                                i_result<=resize(signed(i_C)+i_rmul,DATA_WIDTH*2);
            when "011" => --- R=R+(A+B)
                                i_rmul<=(signed(i_A)+signed(i_B));
                                i_result<=resize(i_result+i_rmul,DATA_WIDTH*2);
            when "100" => --- R=C+(A+B)
                                i_rmul<=(signed(i_A)+signed(i_B));
                                i_result<=resize(signed(i_C)+i_rmul,DATA_WIDTH*2);
            when others => --- default do nothing
                                i_result<=i_result;
                                i_rmul<=    i_rmul;
        end case;
    end if;
end if;

if i_result<MIN then R <=std_logic_vector(to_signed(MIN,DATA_WIDTH));
    elsif i_result>MAX then R <=std_logic_vector(to_signed(MAX,DATA_WIDTH));
    else R<=std_logic_vector(i_result(DATA_WIDTH-1 downto 0));
end if;

end process;
end Behavioral;
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 04:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01348 секунд с 7
ELECTRONIX ©2004-2016