eugen_pcad_ru 0 24 июня, 2015 Опубликовано 24 июня, 2015 · Жалоба Всем доброго времени суток! Написал под Spartan-6 на VHDL простенький аккумулятор (код прилагаю). Но с целью повышения рабочей частоты (разрядность 30 бит, частота где-то 100 МГц) возникла идея задействовать для этих целей встроенные блоки DSP48A. Добавил еще две строки attribute USE_DSP48: string; attribute USE_DSP48 of simple_accum: entity is "yes"; (в прилагаемом файле они закомментированы). В Summary от ISE 14.7 появляются блоки DSP, но в большом количестве (34 из 180). Да и частоту не удалось повысить. По всей видимости что-то делаю не так. Прошу помощи. Заранее спасибо за любые рекомендации по оптимизации кода с целью повышения быстродействия! simple_accum.vhd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Amurak 0 24 июня, 2015 Опубликовано 24 июня, 2015 · Жалоба Простенький аккумулятор - это: accum <= accum + sxt(data, 48); А у вас что-то посложнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eugen_pcad_ru 0 25 июня, 2015 Опубликовано 25 июня, 2015 · Жалоба 2Amurak: Пусть будет "не простенький" ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Amurak 0 25 июня, 2015 Опубликовано 25 июня, 2015 · Жалоба Я бы даже сказал "очень не простенький". Вы что получить-то хотите? Что должен делать блок? Я не стал разбираться, увидев после беглого просмотра использование переменных, функции и оператора "mod". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 25 июня, 2015 Опубликовано 25 июня, 2015 · Жалоба Зачем функция stdv_to_nat? Достаточно unsigned(), а в общем случае to_integer(unsigned()). Зачем shared variable? Они в основном нужны для описания многопортовой памяти, в данном случае лучше использовать signal. С shared variable можно случайно словить глюк, так как не будет запрещено её изменение из нескольких процессов. mod приводит к вставке функции деления, которое, собственно, и тормозит, вместо mod надо использовать сравнение с модулем и вычитание. Так должно получится примерно 170МГц, если ещё конвейеризовать, можно довести до 300, с латентностью около 4 относительно step. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eugen_pcad_ru 0 25 июня, 2015 Опубликовано 25 июня, 2015 · Жалоба Основная задача модуля состоит в вычислении выражения "Count := (Count + stdv_to_nat(step)) mod Modulus;" Все остальное по большому счету не нужно. Попробую переделать с учетом рекомендаций. А еще был бы не плох пример с использованием предлагаемой выше конструкции "accum <= accum + sxt(data, 48)" с использованием DSP и без использования. P.S.: Критика хороша. Но к сожалению пока дельных советов по теме вопроса не увидел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
FakeDevice 0 25 июня, 2015 Опубликовано 25 июня, 2015 (изменено) · Жалоба Всем доброго времени суток! Написал под Spartan-6 на VHDL простенький аккумулятор (код прилагаю). Но с целью повышения рабочей частоты (разрядность 30 бит, частота где-то 100 МГц) возникла идея задействовать для этих целей встроенные блоки DSP48A. Возможно, не в курсе всех тонкостей, но почему бы не использовать вместо этого конвейерный многотактовый сумматор/аккумулятор? Недавно пришлось в силу острой недостаточности DSP написать подобное. Смысл -- разбить на несколько сложений такой разрядности, чтобы успевало за такт защелкиваться. Я добился результата -- сложение двух 32-разрядных чисел на два такта, сложение двух 48-разрядных на 9 тактов. Второй вариант с довольно большим запасом, т.к. плисина забита на 80% и много узких мест. и всё замечательно работает на 300MHz на самом медленном Virtex4. Но если оно правда того стоит и оправдано реальными условиями. Т.к. аккумулятор чуть сложнее будет написать. Да и больше места будет занимать, нежели простое суммирование. Стратегия вам виднее должна быть. ЗЫЖ Если всё-таки будет интересно данное направление, немного подскажу, как на логике можно сделать аккумулятор, где может быть применим многотактовый сумматор. Главная прелесть подхода в том, что, в принципе, нет ограничений по разрядности аккумулятора вообще. Будет лишь увеличиваться задержка конвейера. схемка рассчитана на однотактовые сумматоры, но сюда без потери принципа работы могут быть встроены и многотактовые: -- _________________________________ -- | | -- | rg1 rg2 | sum2 -- ___|___ _____ _____ | _______ -- DIN ————|I1+I2=O|——————|D O|—•——————|D | | | | outrg -- | | | | | | | | | | _____ -- | | CLK——|> | | CLK——|> O|—•—|I1+I2=O|—————|D O|—— DOUT -- |_______| |__R__| | |__R__| |___|___| | | -- sum1 | | | | CLK——|> | -- | | _|_ | |__R__| -- | |_______/ | \________| | -- | | | -- RST _______•______________•_______________________| -- Конечно, придется поморочиться день-два, а если сделать это более универсальным (знак/беззнак, произвольные разрядности и т.д), то, может, и от недельки, но зато будете иметь под рукой такой вот полезный аккумулятор... без границ )) Изменено 25 июня, 2015 пользователем FakeDevice Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Amurak 0 25 июня, 2015 Опубликовано 25 июня, 2015 · Жалоба Основная задача модуля состоит в вычислении выражения "Count := (Count + stdv_to_nat(step)) mod Modulus;" Для начала неплохо было бы поискать реализацию операции "mod", да еще чтобы работала на нужной частоте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 26 июня, 2015 Опубликовано 26 июня, 2015 · Жалоба Для начала неплохо было бы поискать реализацию операции "mod", да еще чтобы работала на нужной частоте. К примеру, на C сложение по модулю можно написать так: int add_mod(int a, int b, int mod){ int b_m_mod = b-mod; int sum = a+b; int sum1 = a+b_m_mod; return sum1 >= 0 ? sum1: sum; } На VHDL аналогично:). Ну и положить его на конвейер, как советует FakeDevice, с предварительным вычислением b-mod за пределами петли обратной связи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
eugen_pcad_ru 0 27 июня, 2015 Опубликовано 27 июня, 2015 · Жалоба Спасибо! В сторону конвейера смотрел. Но этот вариант оставил на "после экспериментов с DSP". Буду пробовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 29 июня, 2015 Опубликовано 29 июня, 2015 · Жалоба ДСП48 в ксалинксе могут сами быть аккумуляторами, в их мануале (ищите на сайте ксалинкса pdf) есть пример их использования в таком виде, вроде как... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 29 июня, 2015 Опубликовано 29 июня, 2015 · Жалоба ДСП48 в ксалинксе могут сами быть аккумуляторами, в их мануале (ищите на сайте ксалинкса pdf) есть пример их использования в таком виде, вроде как... Могут, но не для сложения по модулю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 29 июня, 2015 Опубликовано 29 июня, 2015 · Жалоба так на выход ставиться еще 1 ДСП блок в котором полученное число - модуль. и если оно стало положительным, перебрасывается в 1 блок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 14 августа, 2015 Опубликовано 14 августа, 2015 · Жалоба Могут, но не для сложения по модулю.И вообще, не на языке описания. А только макрокомпонентом. Подробности тут Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sallador 0 20 августа, 2015 Опубликовано 20 августа, 2015 · Жалоба Задам вопрос здесь, если позволите. Есть простой код на VHDL: signal data : std_logic_vector(WIDTH-1 downto 0); attribute use_dsp48 : string; attribute use_dsp48 of data : signal is "yes"; begin pr_cnt: process(rst, clk) begin if (rst = '1') then data <= (others => '0'); elsif rising_edge(clk) then if ena = '1' then data <= data + '1' after td; end if; end if; end process; cnt_out <= data; При разводке хотелось бы задествовать регистр PREG внутри DSP блока. Атрибут KEEP не помог, как бы я его не крутил (хотя он нужен как раз для выноса регистров вне DSP). Xilinx: XST by default tries to infer and implement the maximum macro configuration, including as many registers as possible in the DSP48 Реально ли для счетчика задействовать PREG? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться