mixa7109 0 7 февраля, 2021 Опубликовано 7 февраля, 2021 · Жалоба Добрый день всем. Создаю один проект на больших скоростях и мне там необходимо складывать и накапливать большие значения (разрядность вектора более 50). Естественно проседает быстродействие и необходимо ввести латентность на сумматоре (хотя бы 2). На вход сумматора подаётся значения, которые изменяют по линейному закону с каким-то произвольным коэффициентом. Например входные данные могут быть 1,2,3,4,5 и т.д. А на выходе соответственно получаем 1,3,6,10,15. Схема классическая: выход сумматора падает на вход регистра, а его выход на второй вход сумматора. Регистр может инициировать любым значением перед началом работы. Классический аккумулятор! Есть варианты по добавлению второго сумматора для параллельного счета, но пока не удается засунуть его так, чтобы все работало. У кого-нибудь есть мысли, как увеличить быстродействие?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Самурай 12 7 февраля, 2021 Опубликовано 7 февраля, 2021 · Жалоба 49 минут назад, mixa7109 сказал: У кого-нибудь есть мысли, как увеличить быстродействие?? Вот так: + Retiming Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба 4 hours ago, Самурай said: Вот так: + Retiming либо ваш вход, дециматор(счетный триггер) и обычный аккумулятор на выходе + мультицикл) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mixa7109 0 8 февраля, 2021 Опубликовано 8 февраля, 2021 (изменено) · Жалоба 10 часов назад, Самурай сказал: Вот так: + Retiming Вот описал схему. n_reset_adder <= miStart and n_reset; add_sub1: lpm_add_sub generic map ( lpm_direction => "UNUSED", lpm_representation => data_type, lpm_width => WIDTH_RG ) port map ( clock => clk, clken => miValid, aclr => not n_reset_adder, add_sub => miType, dataa => data_reg, datab => wire_dataB(0), result => wire_out(0) ); process(clk, n_reset) begin if n_reset = '0' then elsif rising_edge(clk) then wire_dataB(0) <= data_reg; wire_dataB(2) <= wire_out(1); wire_dataB(2) <= wire_dataB(1); end if; end process; add_sub2: lpm_add_sub generic map ( lpm_direction => "UNUSED", lpm_representation => data_type, lpm_width => WIDTH_RG ) port map ( clock => clk, clken => miValid, aclr => not n_reset_adder, add_sub => miType, dataa => wire_out(0), datab => wire_dataB(2), result => wire_out(1) ); moData <= wire_out(1); data_reg(WIDTH_DATA - 1 downto 0) <= miData; Результат не сходится с ожиданием, что я не так делаю? А вот схема из квартуса Изменено 8 февраля, 2021 пользователем mixa7109 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Приветствую! 11 hours ago, mixa7109 said: У кого-нибудь есть мысли, как увеличить быстродействие?? Вариантов несколько: Первый считать двумя сумматорами отдельно четные и нечетные отсчеты, что в купе с multicycle констрейнами сделает виртуальную частоту счета в 2 раза ниже, Второй - "разделить" сумматор pipeline регистрами на несколько стадий (по N/2 бит) с регистром в цепи переноса между ними что уменьшит критическую длину логики сумматора. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mixa7109 0 8 февраля, 2021 Опубликовано 8 февраля, 2021 (изменено) · Жалоба 4 минуты назад, RobFPGA сказал: Приветствую! Вариантов несколько: Первый считать двумя сумматорами отдельно четные и нечетные отсчеты, что в купе с multicycle констрейнами сделает виртуальную частоту счета в 2 раза ниже, Второй - "разделить" сумматор pipeline регистрами на несколько стадий (по N/2 бит) с регистром в цепи переноса между ними что уменьшит критическую длину логики сумматора. Удачи! Rob. Можно поподробнее про первый вариант? Пытался его реализовать, но на выходные получалось опять же не то , что надо Изменено 8 февраля, 2021 пользователем mixa7109 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Самурай 12 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба 32 минуты назад, mixa7109 сказал: Результат не сходится с ожиданием, что я не так делаю? process(clk, n_reset) begin if n_reset = '0' then elsif rising_edge(clk) then wire_dataB(0) <= data_reg; wire_dataB(2) <= wire_out(1); -- Должно быть так: wire_dataB(1) <= wire_out(1); wire_dataB(2) <= wire_dataB(1); end if; end process; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mixa7109 0 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Только что, Самурай сказал: process(clk, n_reset) begin if n_reset = '0' then elsif rising_edge(clk) then wire_dataB(0) <= data_reg; wire_dataB(2) <= wire_out(1); -- Должно быть так: wire_dataB(1) <= wire_out(1); wire_dataB(2) <= wire_dataB(1); end if; end process; Я этот момент исправил, я когда построил rtl схему, увидел, что не так, а вот поправить в сообщении забыл. Вообщем, там так, как "должно быть так" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Самурай 12 8 февраля, 2021 Опубликовано 8 февраля, 2021 (изменено) · Жалоба 19 минут назад, mixa7109 сказал: Я этот момент исправил, я когда построил rtl схему, увидел, что не так, а вот поправить в сообщении забыл. Вообщем, там так, как "должно быть так" Тогда подозреваю, что Вам надо добавить в секцию generic map для lpm_add_sub вот такую строчку: LPM_PIPELINE => 0, Изменено 8 февраля, 2021 пользователем Самурай Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Приветствую! 38 minutes ago, mixa7109 said: Можно поподробнее про первый вариант? Пытался его реализовать, но на выходные получалось опять же не, что надо Делите поток на четные/нечетные отсчеты, задерживаете четные на 1 такт, получаете 2 потока с вдвое меньшей частотой обновления, накапливаете в 2 сумматорах, выход с которых тоже суммируете. Но в вашем случае думаю проще второй вариант c pipeline сумматора. И обновления суммы каждый такт, и головной боли с констрейнами не будет. Spoiler assign {din_h, din_l} = din; assign sum = {sum_h1, sum_l1}; always_ff @(posedge clk) begin clear0 <= clear; if (clear) begin {cy0, sum_l0} <= '0; din_h0 <= '0; end else begin {cy0, sum_l0} <= sum_l0 + din_l; din_h0 <= din_h; end if (clear0) begin sum_l1 <= '0; sum_h1 <= '0; end else begin sum_l1 <= sum_l0; sum_h1 <= sum_h1 + din_h0 + cy0; end end Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mixa7109 0 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба 2 часа назад, RobFPGA сказал: Приветствую! Делите поток на четные/нечетные отсчеты, задерживаете четные на 1 такт, получаете 2 потока с вдвое меньшей частотой обновления, накапливаете в 2 сумматорах, выход с которых тоже суммируете. Но в вашем случае думаю проще второй вариант c pipeline сумматора. И обновления суммы каждый такт, и головной боли с констрейнами не будет. Скрыть содержимое assign {din_h, din_l} = din; assign sum = {sum_h1, sum_l1}; always_ff @(posedge clk) begin clear0 <= clear; if (clear) begin {cy0, sum_l0} <= '0; din_h0 <= '0; end else begin {cy0, sum_l0} <= sum_l0 + din_l; din_h0 <= din_h; end if (clear0) begin sum_l1 <= '0; sum_h1 <= '0; end else begin sum_l1 <= sum_l0; sum_h1 <= sum_h1 + din_h0 + cy0; end end Удачи! Rob. Да, я попробую реализовать второй способ. Можете подробнее описать, как и что должно происходить? И представленный код относится к какому варианту? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 168 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Наверное, имеется ввиду загрузить в чётный аккумулятор ноль, в нечётный А, затем суммировать каждый с 2А и чередовать выходы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Приветствую! 3 hours ago, mixa7109 said: Да, я попробую реализовать второй способ. Можете подробнее описать, как и что должно происходить? И представленный код относится к какому варианту? Ко второму варианту: Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mixa7109 0 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Вообщем вот такая упрощенная схемы вышла у меня. Если кому-то интересна реализация этой схемы на vhdl пишите) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 8 февраля, 2021 Опубликовано 8 февраля, 2021 · Жалоба Приветствую! Just now, mixa7109 said: Вообщем вот такая упрощенная схемы вышла у меня. Если кому-то интересна реализация этой схемы на vhdl пишите) Выход cout тоже должен проходит через регистр иначе эта схема смысла не имеет. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться