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

 
 
> 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
 
Start new topic
Ответов (1 - 7)
serjj
сообщение Jan 26 2015, 12:44
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 527
Регистрация: 4-06-14
Из: Санкт-Петербург
Пользователь №: 81 866



Объявите DSP48 явно через добавление макрофункции (через Logicore или вручную) и описывайте задержки через соответствующие параметры и режим работы через шину OPMODE дсп слайса. У вас я вижу большой мультиплексор, в котором большой объем умножений/сложений, ISE/Vivada скорее всего не имплиментирует их как надо, т.к. описано некорректно. Самое надежное - сделать через явное описание. Тогда будет работать строго так как вы напишите, а не так как вас поймет синтезатор.

Сообщение отредактировал serjj - Jan 26 2015, 12:45
Go to the top of the page
 
+Quote Post
count_enable
сообщение Jan 26 2015, 13:02
Сообщение #3


Местный
***

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



Да нет, ISE14.3 распознаёт DSP48 и в финальном синтезе он есть. Но вместо хотя бы 350+ МГц получаю 185.
Go to the top of the page
 
+Quote Post
serjj
сообщение Jan 26 2015, 13:38
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 527
Регистрация: 4-06-14
Из: Санкт-Петербург
Пользователь №: 81 866



Если я напишу y <= a * b; то да он распознает его, и поставит туда. Но с какими параметрами и дополнительной логикой он его поставит? Вы смотрели в RTL Viewer как он синтезировал ваш код, насколько оптимальным получился синтез? Мне сдается, что часть кода имплиментировалась в DSP48, а часть сделалась на логике, из-за чего у вас и наблюдается падение частоты. У вас Spartan 6? Если да, то 350 МГц заявлены только для DSP48, если сигнал проходит еще и через логику, то максимальная частота будет не больше 220-250 МГц в лучшем случае.
Go to the top of the page
 
+Quote Post
count_enable
сообщение Jan 26 2015, 14:14
Сообщение #5


Местный
***

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



Virtex 5, должно быть ок. 550 МГц. К сожалению я не настолько хорош в RTL чтобы понять в чем беда. Переделал по образцу "Sequential Complex Multipliers HDL Coding Techniques" из XST UG, частота поднялась вдвое. Но вот понять в чём беда - не понял sad.gif.
Go to the top of the page
 
+Quote Post
serjj
сообщение Jan 26 2015, 14:22
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 527
Регистрация: 4-06-14
Из: Санкт-Петербург
Пользователь №: 81 866



Выложите здесь код, как он выглядет теперь, пожалуйста, что бы тема была наглядна.
Go to the top of the page
 
+Quote Post
count_enable
сообщение Jan 26 2015, 15:06
Сообщение #7


Местный
***

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



Подумал и решил что операция типа A+B+C мне не особо и нужна, а если очень надо то можно ее сконструировать из МАСов.

Код
--
-- Sequential Complex Multiplier
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity alu_pipelined is
generic(DATA_WIDTH:positive:=18;
        MAX:integer :=255;
        MIN:integer :=-255;
        RES_WIDTH:positive:=48);
port(
            CLK:in std_logic;
            RST:in std_logic;
            A:in signed(DATA_WIDTH-1 downto 0);
            B:in signed(DATA_WIDTH-1 downto 0);
            C:in signed(DATA_WIDTH-1 downto 0);
            OPCODE:in std_logic_vector(1 downto 0);
            RES:out signed(DATA_WIDTH-1 downto 0)
            );
end alu_pipelined;
architecture beh of alu_pipelined is
constant P_WIDTH: integer:=DATA_WIDTH+DATA_WIDTH;
signal oper_load0: std_logic:='0';
signal oper_addsub0: std_logic:='0';
signal p1: signed(P_WIDTH-1 downto 0):=(others=>'0');
signal oper_load1: std_logic:='0';
signal oper_addsub1: std_logic:='0';
signal res0, res1: signed(RES_WIDTH-1 downto 0);
begin
process (clk)
variable acc: signed(RES_WIDTH-1 downto 0);
begin
if rising_edge(clk) then
    if RST='1' then
        acc:=(others=>'0');
        res0<=(others=>'0');
        p1<=(others=>'0');
    else
        oper_load0<= OPCODE(1);
        oper_addsub0 <= OPCODE(0);
        p1 <= A*B;
        oper_load1<= oper_load0;
        oper_addsub1 <= oper_addsub0;
            if (oper_load1='1') then
                acc := res0;
            else
                acc := resize(signed(C),RES_WIDTH);
            end if;
            if (oper_addsub1='1') then
                res0 <= acc-p1;
            else
                res0 <= acc+p1;
            end if;
    end if;
end if;
            if res0>MAX then res1<=to_signed(MAX,RES_WIDTH);
            elsif res0<MIN then res1<=to_signed(MIN,RES_WIDTH);
            else res1<=res0;
            end if;
end process;
RES <= resize(res1,DATA_WIDTH);
end architecture;
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Jan 26 2015, 16:32
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!

Если хотите чтобы синтезатор автоматом пиплайнл регистры в умножитель и пытался впихнуть все в DSP48 блоки то используйте только синхронный reset! (ну или вообще не используйте - для потока данных это не столь обязательно)!

Успехов! Rob.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 15:15
Рейтинг@Mail.ru


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