Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Умножители 36x32
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
alxkon
Здарова Все!

Столкнулся с такой ситуацией - проект на Спартане 6, присутствуют несколько умножителей
36х32, тактовая макс. 46МГц - 6 DSP48 + LUTы ( ISE 13.1 ).
Кроме того есть другие умножители 34х32, 22х18, по ним пока замечаний нет.
Можно конечно CoreGen наделать и пораспихать по нужным местам все умножители.
Вопрос кто сталкивался - естъ ли смысл написатъ универсальный код с чтобы контролироватъ
поведение синтезатора, намекнув ему что составляющие базовые умножители размером 18х18 ?

Или овчинка выделки не стоит?

Спасибо!
Koluchiy
А сейчас как у Вас умножители описаны?
tegumay
код в студию чтоли... маловато это для спартана

асинхронный умножитель чтоли? конвеер включите

много дсп для 32*36 вроде меньше должно быть
litv
Цитата(tegumay @ Jun 27 2011, 23:33) *
код в студию чтоли... маловато это для спартана

асинхронный умножитель чтоли? конвеер включите

много дсп для 32*36 вроде меньше должно быть

Рекурсивные фильтры видимо делаете. Перейдите в нерекурсивным , на низкой как говорите частоте и 18х18
полетят .
alxkon
Цитата(tegumay @ Jun 27 2011, 22:33) *
код в студию чтоли... маловато это для спартана

асинхронный умножитель чтоли? конвеер включите

много дсп для 32*36 вроде меньше должно быть



Код не мой, вот:
CODE

-----------------

--! Standard libraries
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


--! Entity
entity a_mult is
generic(
ARITH_DATA_A_MSB : integer; --! Data input A bus MSB
ARITH_DATA_B_MSB : integer; --! Data input B bus MSB
RESULT_DATA_MSB : integer --! Result data bus MSB
);
port(
-- Main
rst : in std_logic; --! Asynchronous reset
clk : in std_logic; --! Clock
-- Memory
a : in std_logic_vector(ARITH_DATA_A_MSB downto 0); --! Arithmetic port a write data
b : in std_logic_vector(ARITH_DATA_B_MSB downto 0); --! Arithmetic port b write data
p : out std_logic_vector(RESULT_DATA_MSB downto 0) --! Arithmetic result read data
);
end a_mult;

--! Architecture
architecture rtl of a_mult is

-- Width of the intermediate result value
constant RESULT_WIDTH : natural := get_min((RESULT_DATA_MSB+1),(ARITH_DATA_A_MSB+1+ARITH_DATA_B_MSB+1));

signal a_p2 : signed(ARITH_DATA_A_MSB downto 0);
signal b_p2 : signed(ARITH_DATA_B_MSB downto 0);
signal p1 : signed(ARITH_DATA_A_MSB+1+ARITH_DATA_B_MSB downto 0);

begin

-- Connect result data to output ports
-- * Drop rightmost bits if RESULT_DATA_MSB is smaller than ARITH_DATA_A_MSB+1+ARITH_DATA_B_MSB
-- * Fill left side with sign bit if RESULT_DATA_MSB is bigger than ARITH_DATA_A_MSB+1+ARITH_DATA_B_MSB
p <= std_logic_vector(resize(p1(ARITH_DATA_A_MSB+1+ARITH_DATA_B_MSB downto (ARITH_DATA_A_MSB+1+ARITH_DATA_B_MSB)-(RESULT_WIDTH-1)), RESULT_DATA_MSB+1));

p_seq : process(rst, clk)
begin
if ( rst = '1') then

a_p2 <= (others => '0');
b_p2 <= (others => '0');

p1 <= (others => '0');

elsif (rising_edge(clk)) then

-- Capture input data to pipeline registers
a_p2 <= signed(a);
b_p2 <= signed(cool.gif;

-- Multiply registered values
p1 <= a_p2 * b_p2;

end if;
end process p_seq;

end rtl;

---------------

этот примитив использован во многих местах проекта, сответственно в зависимости от генериков умножитель может принять форму и 18х18
и 36х32 и тд.

Цитата(Koluchiy @ Jun 27 2011, 21:53) *
А сейчас как у Вас умножители описаны?

Думаю переписать на будущее на манер

0. Регистрируем А и Б
1. Вход А разбиваем на младшие беззнаковые части (по 18бит ) и старшую знаковую (от 1 до 18бит, взависимости от)
2. Вход Б разбиваем на младшие беззнаковые части (по 18бит ) и старшую знаковую (от 1 до 18бит, взависимости от)
3. Перемножаем соответствующие части с друг с другом, таким же способом p <=a*b. При этом даем свободу синтезатору самому решить когда использовать DSP48 или LUTы
При 18х2 будут LUTы а 18х15 DSP48,
4. Регистрируем результаты
5. Сдвигаем соответствующие результаты влево и суммируем
6. Регистрируем конечный результат

Вопрос есть ли смысл ?
des00
Цитата(antsu88 @ Jun 28 2011, 02:50) *
Вопрос есть ли смысл ?

нет, лучше взять непосредственный инстанс корки и вынести параметр MULT_PIPE для настройки
Hoodwin
Имхо, вся беда в том, что за один такт аппаратный умножитель большой разрядности не выводится. Еще нужно проверить, что разрешен вывод (inferring) умножителей из формального описания.
Но в целом лучше переписать так, чтобы промежуточные результаты умножения попадали в регистры, а не просто суммировались. Тогда конвейерная задержка станет 2 или 3, и производительность будет выше.
alxkon
Цитата(des00 @ Jun 28 2011, 11:56) *
нет, лучше взять непосредственный инстанс корки и вынести параметр MULT_PIPE для настройки

Скажу честно, я туплю, не понимаю как это сделать?
des00
Цитата(antsu88 @ Jun 28 2011, 04:02) *
Скажу честно, я туплю, не понимаю как это сделать?

для альтеры так
Код
`ifdef __USE_ALTERA_MACRO__
      lpm_mult
      #(
        .lpm_hint           ( "INPUT_B_IS_CONSTANT=NO,DEDICATED_MULTIPLIER_CIRCUITRY=YES,MAXIMIZE_SPEED=5" ) ,
        .lpm_widtha         ( pIDAT_W                                                                      ) ,
        .lpm_widthb         ( pDAT2COE_W                                                                   ) ,
        .lpm_widthp         ( cMULT_W                                                                      ) ,
        .lpm_widths         ( 1                                                                            ) ,
        .lpm_type           ( "LPM_MULT"                                                                   ) ,
        .lpm_representation ( "SIGNED"                                                                     ) ,
        .lpm_pipeline       ( 2                                                                            )        // do as parameter
      )
      lpm_mult
      (
        .dataa  ( oerr        ),
        .datab  ( dat2coe [i] ),
        .clken  ( iclkena     ),
        .clock  ( iclk        ),
        .result ( mult    [i] ),
        .aclr   ( 1'b0        ),
        .sum    ( 1'b0        )
      );
`endif


Цитата(Hoodwin @ Jun 28 2011, 03:50) *
Но в целом лучше переписать так

а смысл? корегенератор сделает тоже самое, для этого достаточно указать кол-во ступеней конвейеризации.
Hoodwin
Смысл в том, что коргенераторы разные у разных фирм, а формальное описание может быть общее, а реальные умножители выделяются из него синтезатором.
Конечно, иногда проще дернуть визард и попросить его сделать вариацию на тему умножителя и потом для другого семейства сделать то же самое еще раз. Я обычно в таких случаях делаю два исходника с общим entity name, и потом вставляю в проект один из них.
des00
Цитата(Hoodwin @ Jun 28 2011, 05:10) *
Смысл в том, что коргенераторы разные у разных фирм, а формальное описание может быть общее, а реальные умножители выделяются из него синтезатором.
Конечно, иногда проще дернуть визард и попросить его сделать вариацию на тему умножителя и потом для другого семейства сделать то же самое еще раз. Я обычно в таких случаях делаю два исходника с общим entity name, и потом вставляю в проект один из них.

механизм макросов помогает сделать и независимый сорец и корку от любого производителя вставить, а корегенератор нужен для того что бы один раз скопировать инстанс аппаратного умножителя, со всеми параметрами из корки и использовать его.
alxkon
Цитата(des00 @ Jun 28 2011, 13:54) *
для альтеры так
Код
`ifdef __USE_ALTERA_MACRO__
      lpm_mult
      #(
        .lpm_hint           ( "INPUT_B_IS_CONSTANT=NO,DEDICATED_MULTIPLIER_CIRCUITRY=YES,MAXIMIZE_SPEED=5" ) ,
        .lpm_widtha         ( pIDAT_W                                                                      ) ,
        .lpm_widthb         ( pDAT2COE_W                                                                   ) ,
        .lpm_widthp         ( cMULT_W                                                                      ) ,
        .lpm_widths         ( 1                                                                            ) ,
        .lpm_type           ( "LPM_MULT"                                                                   ) ,
        .lpm_representation ( "SIGNED"                                                                     ) ,
        .lpm_pipeline       ( 2                                                                            )        // do as parameter
      )
      lpm_mult
      (
        .dataa  ( oerr        ),
        .datab  ( dat2coe [i] ),
        .clken  ( iclkena     ),
        .clock  ( iclk        ),
        .result ( mult    [i] ),
        .aclr   ( 1'b0        ),
        .sum    ( 1'b0        )
      );
`endif



а смысл? корегенератор сделает тоже самое, для этого достаточно указать кол-во ступеней конвейеризации.


Спасибо за наводку. Однако Ксилинкс сделал макрос только для 22х18 максимально. По этому придется дорабатывать напильником sm.gif

===================
Elaborating entity <MULT_MACRO> (architecture <mult>) with generics from library <unimacro>.
WARNING:HDLCompiler:321 - "N:/O.40d/rtf/devlib/vhdl/src/unimacro/MULT_MACRO.vhd" Line 63: Comparison between arrays of unequal length always returns FALSE.
WARNING:HDLCompiler:321 - "N:/O.40d/rtf/devlib/vhdl/src/unimacro/MULT_MACRO.vhd" Line 82: Comparison between arrays of unequal length always returns FALSE.
WARNING:HDLCompiler:321 - "N:/O.40d/rtf/devlib/vhdl/src/unimacro/MULT_MACRO.vhd" Line 101: Comparison between arrays of unequal length always returns FALSE.
ERROR:HDLCompiler:1242 - "N:/O.40d/rtf/devlib/vhdl/src/unimacro/MULT_MACRO.vhd" Line 144: "Illegal value of Attribute WIDTH_B : 22. Legal values of this attribute are 1 to 18 ":
===================
des00
Цитата(antsu88 @ Jun 30 2011, 00:54) *
Однако Ксилинкс сделал макрос только для 22х18 максимально. По этому придется дорабатывать напильником sm.gif

вы немножко путаете. макросы это то, с помощью чего я управляю условной компиляцией, а вам нужен инстанс корки умножителя, из unisim например, со всеми параметрами. Его можно получить двумя путями :
1. Набив вручную используя хелп на библиотечные элементы
2. Скопировав из того что сделал корегенератор.

второй способ проще wink.gif
alxkon
Цитата(des00 @ Jun 30 2011, 14:38) *
вы немножко путаете. макросы это то, с помощью чего я управляю условной компиляцией, а вам нужен инстанс корки умножителя, из unisim например, со всеми параметрами. Его можно получить двумя путями :
1. Набив вручную используя хелп на библиотечные элементы
2. Скопировав из того что сделал корегенератор.

второй способ проще wink.gif


CODE

--------------------------------------------------------------------------------
-- You must compile the wrapper file mult_36x32.vhd when simulating
-- the core, mult_36x32. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".

-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY mult_36x32 IS
PORT (
clk : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(35 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(67 DOWNTO 0)
);
END mult_36x32;

ARCHITECTURE mult_36x32_a OF mult_36x32 IS
-- synthesis translate_off
COMPONENT wrapped_mult_36x32
PORT (
clk : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(35 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(67 DOWNTO 0)
);
END COMPONENT;

-- Configuration specification
FOR ALL : wrapped_mult_36x32 USE ENTITY XilinxCoreLib.mult_gen_v11_2(behavioral)
GENERIC MAP (
c_a_type => 0,
c_a_width => 36,
c_b_type => 0,
c_b_value => "10000001",
c_b_width => 32,
c_ccm_imp => 0,
c_ce_overrides_sclr => 0,
c_has_ce => 0,
c_has_sclr => 0,
c_has_zero_detect => 0,
c_latency => 4,
c_model_type => 0,
c_mult_type => 1,
c_optimize_goal => 1,
c_out_high => 67,
c_out_low => 0,
c_round_output => 0,
c_round_pt => 0,
c_verbosity => 0,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_mult_36x32
PORT MAP (
clk => clk,
a => a,
b => b,
p => p
);
-- synthesis translate_on

END mult_36x32_a;


вот я получил из генератора.
Видно генерики и что оно берется из XilinxCoreLib
Как теперь это модифицировать что бы синтезировалось?!
Ведь XilinxCoreLib это библиотека симуляции?!

des00
Цитата(antsu88 @ Jun 30 2011, 09:07) *
вот я получил из генератора.
Видно генерики и что оно берется из XilinxCoreLib
Как теперь это модифицировать что бы синтезировалось?!

вам нужно добраться до компонента XilinxCoreLib.mult_gen_v11_2(behavioral) и посмотреть что именно оно вставляет. можно пойти другим путем.

рассмотрим на примере виртекса 4 берем доку XtremeDSP for Virtex-4 FPGAs User Guide -> DSP48 Slice Primitive -> инстанс вашего умножителя, с описанием ВСЕХ параметров. Копи пас и у вас есть искомое %)


BlackOps

перенес всетаки в новую тему. извините.
alxkon
Цитата(des00 @ Jun 30 2011, 17:32) *
вам нужно добраться до компонента XilinxCoreLib.mult_gen_v11_2(behavioral) и посмотреть что именно оно вставляет. можно пойти другим путем.

рассмотрим на примере виртекса 4 берем доку XtremeDSP for Virtex-4 FPGAs User Guide -> DSP48 Slice Primitive -> инстанс вашего умножителя, с описанием ВСЕХ параметров. Копи пас и у вас есть искомое %)

Действительно просто! Получилось и работает!
Большое спасибо за подсказку!!!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.