new123 0 15 февраля, 2019 Опубликовано 15 февраля, 2019 (изменено) · Жалоба Форумчане привет. У меня очередной затык, над которым просидел несколько дней =). Спасибо если поможете. Ввел себе такой массив. И такой код с ним. reg [7:0] current_data_recv[0:41]; current_data_size_recv <= current_data_size_recv + 4'h8; if (current_data_size_recv <= 12'd43) begin current_data_recv[current_data_size_recv + 0] <= xgmii_data_rx[63:56]; current_data_recv[current_data_size_recv + 1] <= xgmii_data_rx[55:48]; current_data_recv[current_data_size_recv + 2] <= xgmii_data_rx[47:40]; current_data_recv[current_data_size_recv + 3] <= xgmii_data_rx[39:32]; current_data_recv[current_data_size_recv + 4] <= xgmii_data_rx[31:24]; current_data_recv[current_data_size_recv + 5] <= xgmii_data_rx[23:16]; current_data_recv[current_data_size_recv + 6] <= xgmii_data_rx[15:8]; current_data_recv[current_data_size_recv + 7] <= xgmii_data_rx[7:0]; end Время Fitter выросло с 20мин до 3ч. Что попытался сделать для выправления ситуации: 1) Ну думаю мало ли, может он не может это разложить и оптимизировать из за непонимания логики. Взял, не поленился, разложил все в case case (current_data_size_recv) 12'd1: begin current_data_recv[1] <= xgmii_data_rx[63:56]; current_data_recv[2] <= xgmii_data_rx[55:48]; current_data_recv[3] <= xgmii_data_rx[47:40]; current_data_recv[4] <= xgmii_data_rx[39:32]; current_data_recv[5] <= xgmii_data_rx[31:24]; current_data_recv[6] <= xgmii_data_rx[23:16]; current_data_recv[7] <= xgmii_data_rx[15:8]; current_data_recv[8] <= xgmii_data_rx[7:0]; end 12'd2: begin current_data_recv[2] <= xgmii_data_rx[63:56]; current_data_recv[3] <= xgmii_data_rx[55:48]; current_data_recv[4] <= xgmii_data_rx[47:40]; current_data_recv[5] <= xgmii_data_rx[39:32]; current_data_recv[6] <= xgmii_data_rx[31:24]; current_data_recv[7] <= xgmii_data_rx[23:16]; current_data_recv[8] <= xgmii_data_rx[15:8]; current_data_recv[9] <= xgmii_data_rx[7:0]; end ..... не помогло. 2) Хорошо, значит он (массив) размещается на логике, и просто очень долго оптимизирует пути. Решил его разместить по другому (делаю так впервые) Пробую вот так reg [7:0] current_data_recv[0:41]; /*synthesis syn_ramstyle = "M20K"*/ и пробую вот так (* ramstyle = "M20K"*) reg [7:0] current_data_recv[0:41]; Получаю в ответ Quote Warning (10885): Verilog HDL Attribute warning at xgmii_10g_rx.sv(23): synthesis attribute "syn_ramstyle" with value ""M20K"" has no object and is ignored 3) Еще думаю может сильно зависит от упакованного и неупакованного массива? Честно говоря, разницу в которых я пока не очень улавливаю. Или менять логику тогда совсем и не делать такой массив Подскажите, может будет у кого идея, как эту проблему забороть? Заранее спасибо. Изменено 15 февраля, 2019 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба Приветствую! Для того чтобы корректно синтезировалась память нужно чтобы в дизайне были соответствующие паттерны ее использования. Вот вы пишете reg [7:0] current_data_recv[0:41]; предполагая что память будет 42 слова по 8 бит. А используете ее как? current_data_recv[1] <= xgmii_data_rx[63:56]; ... current_data_recv[8] <= xgmii_data_rx[7:0]; как кучу независимых регистров по 8 бит! Если вам нужно делать памяти с разной разрядностью на чтение/запись то надо понимать что физически одновременно доступ можно иметь только к порту с большей шириной. Тесть вам надо определять память как reg [8*8-1:0] current_data_recv[0 : 5]; и разгуливать запись в отдельные байты одного слова через byte_enable. Ну и естественно нельзя использовать reset для инициализации памяти. В Qu/Vivado есть свои темплейты для памяти. На первых порах старайтесь их придерживаться. Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexadmin 0 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба Вы ведь понимаете что нельзя разместить массив в памяти и писать на одном такте сразу в кучу ячеек (адресов)? Сейчас у вас получился набор 8*42 триггеров. На какой частоте это должно работать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба 31 minutes ago, alexadmin said: На какой частоте это должно работать? 156Mhz Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба 37 minutes ago, RobFPGA said: Если вам нужно делать памяти с разной разрядностью на чтение/запись то надо понимать что физически одновременно доступ можно иметь только к порту с большей шириной. Тесть вам надо определять память как reg [8*8-1:0] current_data_recv[0 : 5]; и разгуливать запись в отдельные байты одного слова через byte_enable. Ну и естественно нельзя использовать reset для инициализации памяти. Да уж, после обычного программирования очень сложно перестроиться на такое мышление. Я думал, я сейчас быстренько сделаю массив на ~40 байт и в него буду запихивать по 8 байт получаемые данные. С удовольствием бы сделал какой нибудь вектор reg [1920:0] и в него последовательно писал бы по 64 бита, но нельзя делать некостантную индексацию к вектору. Придется мне наверное всю логику переделать и уйти от таких больших данных Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба Приветствую! 36 minutes ago, new123 said: Да уж, после обычного программирования очень сложно перестроиться на такое мышление. Я думал, я сейчас быстренько сделаю массив на ~40 байт и в него буду запихивать по 8 байт получаемые данные. ... Придется мне наверное всю логику переделать и уйти от таких больших данных Нужно просто помнить что в отличии от SW в зависимости от написанного кода RTL будет синтезирован либо в параллельное железо либо в последовательное операции. Запихивать по 8 байт в память не проблема. Смотрите в темплейтах разные варианты Mixed-width RAM. Ну и надо помнить что иногда синтез памяти с несколькими портами и разной шириной не всегда возможен из напрямую из RTL - всегда есть случаи когда выгоднее вручную использовать примитивы памяти конкретного семейства. Поэтому проще сделать для себя модули-врапперы с параметрами, реализующие основные паттерны памяти (single port, simple dual-port, true dual-port, mixed-width, ...) И все извраты по оптимизации делать внутри врапперов. Заодно это не позволит вам в основном коде "случайно" лазить в память "куда ни попадя". Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба 5 minutes ago, RobFPGA said: Смотрите в темплейтах разные варианты Mixed-width RAM. Поэтому проще сделать для себя модули-врапперы с параметрами, реализующие основные паттерны памяти (single port, simple dual-port, true dual-port, mixed-width, ...) Правильно ли я понимаю, что вы советуете заюзать какой нибудь RAM IP core и написать к нему обертку? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 15 февраля, 2019 Опубликовано 15 февраля, 2019 · Жалоба Приветствую! 2 hours ago, new123 said: Правильно ли я понимаю, что вы советуете заюзать какой нибудь RAM IP core и написать к нему обертку? Не совсем - сначала написать обертку а потом уж внутри ее уже делать разные реализации c одной и той же функциональностью . Заодно внутри враппера можно сделать некоторый сервис с блекджеком и шлю.. по проверке допустимости комбинаций параметров, логирования актуальной конфигурации, отлов нехороших ситуаций при симуляции, ... Например: // simple dual-port module sdp_ram_wrp #(parameter MODE = "ALTERA_CORE", // "RTL", "ALTERA_RTL", "ALTERA_CORE", "XILINX_RTL", "XILINX_CORE", ... WR_DATA_WH = 8 , // Write port data width WR_BE_WH = 8 , // Write port byte enable width RD_DATA_WH = 8 , // Read port data width DEPTH = 64 , // Number of words (for the wider port) RD_PIPE = 2 // Read pipeline (only 1 or 2) ) ( wr_clk , // write clock wr_addr , // address of write port wr_din , // data of write port wr_ben , // write byte enable wr_wen , // write enable // rd_clk , // Read clock rd_en_i , // Read enable for memory (1st pipeline stage) rd_en_ii , // Read enable for output register (2st pipeline stage) rd_clr_i , // Sync. clear mem register (1st pipeline stage) rd_clr_ii , // Sync. clear output register (2st pipeline stage) rd_addr , // Read address rd_dou // Read data output ); ... generate if (MODE == "RTL") begin : g_rtl ... end else if (MODE == "ALTERA_CORE") begin : g_alt_core ... end else .... ... endgenerate Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 20 февраля, 2019 Опубликовано 20 февраля, 2019 (изменено) · Жалоба Вообщем что я только не делал. Даже массив убрал и оптимизировал все на малом кол-ве регистров, а проблема не ушла. По итогу пришлось овладеть все таки Time Analyzer и дождаться семичасовой компиляции. По итогу опять всплыла проблема из моей другой темы, про переброс данных из одного края плис в другой край плис. По обоим краям плис анализируются поступаемые 8 байт, и потом один модуль ждет от другого определенного сигнала (для защелки данныех). Получается квартус перебирает 7 часов комбинации, как бы защелкнуть вовремя и не может. Воспользовался советом некой "конвейеризации" (ну или FIFO) данных, чтобы рассчет на другом краю плис всегда отставал на пару тактов и успел потом защелкнуться. И теперь можно на этот путь поставить set_false_path или set_max_delay (еще не решил что нужнее). В итоге время компиляции вернулось на 20+мин Изначально получается, вопрос в теме поставил неверно. Изменено 20 февраля, 2019 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 20 февраля, 2019 Опубликовано 20 февраля, 2019 · Жалоба Приветствую! Just now, new123 said: Вообщем что я только не делал. Даже массив убрал и оптимизировал все на малом кол-ве регистров, а проблема не ушла. По итогу пришлось овладеть все таки Time Analyzer и дождаться семичасовой компиляции. По итогу опять всплыла проблема из моей другой темы, про переброс данных из одного края плис в другой край плис. По обоим краям плис анализируются ... Тяжело разобраться с проблемами черных кошек в темноте подвала. Вы бы хоть картинку сделали из чего ваша система состоит и какие блоки обработки имеет. И как эти блоки взаимодействуют. Тогда глядишь и вам станет понятнее что и как, а не только нам телепатам-советчикам Ну и опять же - сразу воевать со стаей черных котов тяжко и долго - надо тренироваться на отдельных кошечках - тестовых упрощенных проектах. Делайте синтезируете и P&R отдельных блоков/модулей вашей системы и смотрите что из этого выходить. Удачи! Rob Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 20 февраля, 2019 Опубликовано 20 февраля, 2019 · Жалоба 2 minutes ago, RobFPGA said: Тяжело разобраться с проблемами черных кошек в темноте подвала. Вы бы хоть картинку сделали из чего ваша система состоит и какие блоки обработки имеет. да да. Я уже думал нарисовать блок схему этой части проекта (я их люблю чертить) и попросить еще раз помощи форума =) Спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 22 февраля, 2019 Опубликовано 22 февраля, 2019 · Жалоба On 2/20/2019 at 10:56 AM, RobFPGA said: . Делайте синтезируете и P&R отдельных блоков/модулей вашей системы и смотрите что из этого выходить. Удачи! Rob Я тут случайно узнал, что Tyme Analyzer можно сделать на Post Map до Fitter. Был несказано рад. Теперь понимаю, что ваш совет может быть очень полезным, но я его не до конца понял. Что такое P&R? Partial Reconfiguration? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 22 февраля, 2019 Опубликовано 22 февраля, 2019 · Жалоба Приветствую! 7 minutes ago, new123 said: Я тут случайно узнал, что Tyme Analyzer можно сделать на Post Map до Fitter. Был несказано рад. Теперь понимаю, что ваш совет может быть очень полезным, но я его не до конца понял. Что такое P&R? Partial Reconfiguration? P&R - Place and Route. Для Qu это почти тоже что Map and Fitter Успехов! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 22 февраля, 2019 Опубликовано 22 февраля, 2019 · Жалоба 42 minutes ago, RobFPGA said: P&R - Place and Route. Для Qu это почти тоже что Map and Fitter спасибо за расшифровку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dvlwork 0 22 февраля, 2019 Опубликовано 22 февраля, 2019 · Жалоба Для Qu это Fitter Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться