Перейти к содержанию
    

Подскажите по оптимизации

Дано: Virtex-6 XC6VLX240T

Центральный модуль, включающий себя UART и подготовку данных.

Есть вычислительные модули, которые коннектятся к центральному, их интерфейс:

(
        clock              : in std_logic;
        reset              : in std_logic;
        
        data_input         : in std_logic_vector(31 downto 0);
        data_flag          : in std_logic;

        done                  : out std_logic;
        data_ready         : out std_logic
)

 

С точки зрения использования ресурсов в плис влезает около 230 таких модулей + центральный.

 

При 64 модулях все это хорошо живет на 200Мгц, данная частота и является целью. При 128 модулях синтезатор уже выдаёт максимальную частоту 140MHz, что не устраивает.

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

Попробовал добавить регистры в эти линии:

signal reset_corebuf              : std_logic_vector(NCORES - 1 downto 0);
signal data_input_corebuf         : std_logic_vector((NCORES * 32) - 1 downto 0);
signal data_flag_corebuf          : std_logic_vector(NCORES - 1 downto 0);
signal done_corebuf                 : std_logic_vector(NCORES - 1 downto 0);
signal data_ready_corebuf         : std_logic_vector(NCORES - 1 downto 0);

    process (clk)
    begin
        if (rising_edge(clk)) then
            for i in 0 to NCORES - 1 loop
                reset_corebuf(i) <= reset;
                data_input_corebuf((i + 1) * 32 - 1 downto i * 32) <= core_data;
                data_flag_corebuf(i) <= data_core_flag(i);
                
                core_done(i) <= done_corebuf(i);
                data_core_ready(i) <= data_ready_corebuf(i);
            end loop;
        end if;
    end process;

И вот эти промежуточные сигналы уже законнектил к вычислительным модулям. Лучше не стало, хотя по логике - должно.

 

Подскажите пожалуйста, что я делаю не так и куда копать)

Изменено пользователем v1vas

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите пожалуйста, что я делаю не так и куда копать)

для начала перестать работать в слепую и выложить схему вашей архитектуры(чем полнее тем лучше), на ней будут видны критические места этой архитектуры. только потом искать решение.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И вот эти промежуточные сигналы уже законнектил к вычислительным модулям. Лучше не стало, хотя по логике - должно.

Подскажите пожалуйста, что я делаю не так и куда копать)

При ручной репликации регистров на все реплицированные сигналы надо повесить атрибут syn_preserve, иначе синтезатор их может оптимизировать в один регистр, из-за чего у вас, вероятно, и не стало лучше. Кроме того, 230*35 - это 8000 независимых длинных линий, которые будут зря жрать электричество и могут переполнить ресурсы интерконнекта. Лучше создать древовидную структуру, например, 16 регистровых групп к центральному блоку, и 8-16 оконечных устройств на каждую регистровую группу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дано: Virtex-6 XC6VLX240T

Центральный модуль, включающий себя UART и подготовку данных.

 

С точки зрения использования ресурсов в плис влезает около 230 таких модулей + центральный.

 

Подскажите пожалуйста, что я делаю не так и куда копать)

Если не вдаваться в детали, то дело выглядит удивительно...

Есть один медленный UART и не понятно кто делает протокол передачи байтов в хост.

Дальше еще удивительней. 230 модулей должны работать ОДНОВРЕМЕННО??? Тогда сколько же длится "Обработка в модуле", если ее результат передается не понятно по какому протоколу через медленный UART.

Почему-то мне кажется, что если сделать многопоточную обработку одним модулем да еще и на 200Мгц, то он вполне справится за то время, пока UART передает-получает данные в хост. Ну, если уж не один модуль, то десятка вполне хватит...

И при таком подходе обнаружится, что кристалл будет заполнен на 10%...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

v1vas

У Вас в FPGA более 800 BRAM.

Если на выходе каждого модуля UART поставить пакетный буфер из BRAM, то станет возможным "перекачивать" данные во входной пакетный буфер в BRAM центрального модуля.

По идее должно улучшить времянку.

А лучше вообще сделать мультиплексор сигналов древовидным, как предложил уважаемый Timmy, да и вообще очень навороченным: из нескольких модулей в одну BRAM.

Присоединюсь к уважаемым des00 и iosifk, что пока архитектура не очень ясна, трудно что-либо толковое посоветовать.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давайте вдаваться в детали, чтобы все не выглядело так ужасно, как это понял iosifk =)

 

Есть вычислительный модуль, в нем достаточно легковесная математика. Он единоразово принимает 34 байта стартовых данных и далее на протяжении примерно 5 500 000 000 шагов (1 шаг - 1 такт) эти данные обрабатывает. При частоте 200МГц - это около 30 секунд. В процессе этих 30 секунд никакие данные модулю больше не нужны. По итогам работы модуля мы на выходе получаем один бит: вычислилось ли интересующее нас значение или нет (флаг data_ready в первом интерфейсе, что я написал). Это происходит в среднем только один раз на 300 000 вариантов входных данных, поэтому мне достаточно просто знать для каких данных это произошло, а все остальное я проверяю на хосте. Ну и соответственно есть флаг done, когда все модули закончили - я им бросаю следующую пачку данных, предварительно принятых по UART, а обратно отправляю номер модуля который что-то вычислил, если он есть.

 

UART - другой частотный домен, заведен на два FIFO - один для отправки данных, один для приемки.

 

Главный модуль: объединяет и контролирует всё это.

 

Общая структура и порядок работы главного модуля:

1) Проверяем FIFO, в котором скапливаются данные прилетевшие с хоста, для каждых 34 байт оказавшихся там - отправляем их в вычислительный модуль.

2) Когда загрузили все модули - ждем, пока все модули посчитают (у всех done = '1')

3) Если у какого-то модуля data_ready = '1' - кидаем номер этого модуля в FIFO для отправки данных на хост

4) Ресетим модули и идем на пункт один

 

Вычислительный модуль:

1) Если data_flag = '1', то в data_input лежат валидные данные.

2) Как накопили 34 байта - начали работу.

3) Если вычислилось то, что нужно data_ready <= '1';

4) Как закончили done <= '1';

 

Изначально вычислительные коннектились к основному прозаично:

MTMainCores:
    for i in 0 to NCORES - 1 generate
    begin
        CoreEntry: CRMain
        GENERIC MAP
        (
            CORE_N => i
        )
        PORT MAP 
        (
            clock => clk,
            reset => reset,
            data_input => core_data,
            data_flag => data_core_flag(i),
            done => core_done(i),
            data_ready => data_mt_ready(i)
        );
    end generate MainCores;

 

Потом добавил регистры, про которые написал в первом сообщении. По совету Timmy добавил им аттрибут "keep":

attribute keep : string;  
attribute keep of reset_corebuf: signal is "true";  
attribute keep of data_input_corebuf: signal is "true";  
attribute keep of data_flag_corebuf: signal is "true";  
attribute keep of done_corebuf: signal is "true";  
attribute keep of data_ready_corebuf: signal is "true";

 

И на текущий момент имею 48084 timing score для 128 модулей и вот такой критический путь:

Paths for end point Mmux__n4665412_FRB (SLICE_X98Y138.D3), 312 paths 
-------------------------------------------------------------------------------- 
Slack (setup path):     -2.621ns (requirement - (data path - clock path skew + uncertainty)) 
   Source:               MTMainCores[3].CoreEntry/data_ready_BRB2 (FF) 
   Destination:          Mmux__n4665412_FRB (FF) 
   Requirement:          5.000ns 
   Data Path Delay:      7.486ns (Levels of Logic = 5) 
   Clock Path Skew:      -0.100ns (1.521 - 1.621) 
   Source Clock:         clk_BUFGP rising at 0.000ns 
   Destination Clock:    clk_BUFGP rising at 5.000ns 
   Clock Uncertainty:    0.035ns 
  
   Clock Uncertainty:          0.035ns  ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE 
     Total System Jitter (TSJ):  0.070ns 
     Total Input Jitter (TIJ):   0.000ns 
     Discrete Jitter (DJ):       0.000ns 
     Phase Error (PE):           0.000ns 
  
   Maximum Data Path at Slow Process Corner: MTMainCores[3].CoreEntry/data_ready_BRB2 to Mmux__n4665412_FRB 
     Location             Delay type         Delay(ns)  Physical Resource 
                                                        Logical Resource(s) 
     -------------------------------------------------  ------------------- 
     SLICE_X70Y134.DQ     Tcko                  0.337   MTMainCores[3].CoreEntry/data_ready_BRB2 
                                                        MTMainCores[3].CoreEntry/data_ready_BRB2 
     SLICE_X70Y132.C1     net (fanout=1)        0.710   MTMainCores[3].CoreEntry/data_ready_BRB2 
     SLICE_X70Y132.C      Tilo                  0.068   data_mt_ready<3> 
                                                        MTMainCores[3].CoreEntry/data_ready_rstpot 
     SLICE_X97Y70.B3      net (fanout=5)        2.967   data_ready_corebuf<3> 
     SLICE_X97Y70.B       Tilo                  0.068   data_mt_ready<7> 
                                                        Mmux__n466542 
     SLICE_X98Y112.D6     net (fanout=1)        1.627   N19372 
     SLICE_X98Y112.D      Tilo                  0.068   MTMainCores[21].CoreEntry/SM_STATE_FSM_FFd4_BRB1 
                                                        Mmux__n466544 
     SLICE_X98Y138.C5     net (fanout=1)        1.158   N19376 
     SLICE_X98Y138.C      Tilo                  0.068   Mmux__n4665412_FRB 
                                                        N19384 
     SLICE_X98Y138.D3     net (fanout=1)        0.345   N19384 
     SLICE_X98Y138.CLK    Tas                   0.070   Mmux__n4665412_FRB 
                                                        Mmux__n4665412 
                                                        Mmux__n4665412_FRB 
     -------------------------------------------------  --------------------------- 
     Total                                      7.486ns (0.679ns logic, 6.807ns route) 
                                                        (9.1% logic, 90.9% route)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Общая структура и порядок работы главного модуля:

1) Проверяем FIFO, в котором скапливаются данные прилетевшие с хоста, для каждых 34 байт оказавшихся там - отправляем их в вычислительный модуль.

2) Когда загрузили все модули - ждем, пока все модули посчитают (у всех done = '1')

3) Если у какого-то модуля data_ready = '1' - кидаем номер этого модуля в FIFO для отправки данных на хост

4) Ресетим модули и идем на пункт один

 

Вычислительный модуль:

1) Если data_flag = '1', то в data_input лежат валидные данные.

2) Как накопили 34 байта - начали работу.

3) Если вычислилось то, что нужно data_ready <= '1';

4) Как закончили done <= '1';

понятно, майнер делаете. Интерфейс ваших данных 34 байта и интерфейс результата перенесите в домен низкой частоты UART (CDC поставьте в вычислительные движки), саму шину на запись сделайте что-то вроде вишбона, на чтение соберите все с большой сдвиговый регистр и результат на хост. Ну и констрейны правильные натравить. И все заробит.

 

ЗЫ. схему бы нарисовали себе, все стало бы как на ладони. У меня бойцы в добровольно-принудительном порядке такое делают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не майнер, это очень специфичный брут-форс для очень экзотичной задачи) Но архитектурно идеи те же, согласен.

 

Схему держу в голове, объёма мозга хватает. Но перенесу на бумагу, хорошо, заодно и здесь выложу.

 

За советы спасибо! Начну воплощать.

Изменено пользователем v1vas

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не майнер, это очень специфичный брут-форс для очень экзотичной задачи)

 

 

это что же за брутфорс такой, для реализации которого понадобилось фигачить проект на fpga ))?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давайте вдаваться в детали, чтобы все не выглядело так ужасно, как это понял iosifk =)

 

Есть вычислительный модуль, в нем достаточно легковесная математика. Он единоразово принимает 34 байта стартовых данных и далее на протяжении примерно 5 500 000 000 шагов (1 шаг - 1 такт) эти данные обрабатывает. При частоте 200МГц - это около 30 секунд. В процессе этих 30 секунд никакие данные модулю больше не нужны.

 

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

 

Вот , о чем я и написал... Плохой подход гонять параллельные шины и делать все "в лоб".

 

Сделайте так:

В центральный модуль добавье что-то вроде SPI, который будет передавать-принимать из вычислителей данные в последовательном коде. При 30 сек добавить еще несколько тактов на 34 бита - думаю что это проблемой не будет...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Передача через входную шину идёт редко. Дёргайте data_flag не каждый такт, а раз в три такта плюс set_multicycle_path.

PS. Брутфорс экономичнее делать на более мелких ПЛИС как вот эти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот , о чем я и написал... Плохой подход гонять параллельные шины и делать все "в лоб".

 

Сделайте так:

В центральный модуль добавье что-то вроде SPI, который будет передавать-принимать из вычислителей данные в последовательном коде. При 30 сек добавить еще несколько тактов на 34 бита - думаю что это проблемой не будет...

 

Я бы даже предложил не просто "вроде SPI", а что-то "вроде JTAG". Т.е. последовательную шину развести транзитом через все модули - это сильно экономит интерконнекты. И так же как в JTAG тем для кого информация не предназначена - режим Байпас - это только 1 триггер на приеме. А тому, кто должен получить данные - 34 бита. Про это подробнее - в моих статьях.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...