AltairNsk 0 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба Добрый день Осваиваю плисоводство, на плате MaxII EPM570T100, соответственно quartus 13.0sp1 webedition. Нарисовалась вот такая штука, три вложенных счетчика с параметрами, задающих времянки //input bit_cntmax, word_cntmax if (bit_cnt < bit_cntmax) bit_cnt <= bit_cnt + 1; else bit_cnt <= 0; if (bit_cnt == bit_cntmax) begin if (word_cnt < word_cntmax) word_cnt <= word_cnt + 1; else word_cnt <= 0; end if (bit_cnt == bit_cntmax && word_cnt == word_cntmax) begin if (msg_cnt < MSG_LENGTH) msg_cnt <= msg_cnt + 1; else msg_cnt <= 0; end //output sig = f(bit_cnt, word_cnt, msg_cnt) Привычно глазам, в симуляторе тикает как надо, но в железе не успевает. Можно ли как-то объяснить синтезатору, что тут нужно делать именно счетчики, а не регистры+сумматор+компаратор? Или смириться и привыкать вставлять мегафункции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 19 минут назад, AltairNsk сказал: Добрый день Осваиваю плисоводство, на плате MaxII EPM570T100, соответственно quartus 13.0sp1 webedition. Нарисовалась вот такая штука, три вложенных счетчика с параметрами, задающих времянки //input bit_cntmax, word_cntmax if (bit_cnt < bit_cntmax) bit_cnt <= bit_cnt + 1; else bit_cnt <= 0; if (bit_cnt == bit_cntmax) begin if (word_cnt < word_cntmax) word_cnt <= word_cnt + 1; else word_cnt <= 0; end if (bit_cnt == bit_cntmax && word_cnt == word_cntmax) begin if (msg_cnt < MSG_LENGTH) msg_cnt <= msg_cnt + 1; else msg_cnt <= 0; end //output sig = f(bit_cnt, word_cnt, msg_cnt) Привычно глазам, в симуляторе тикает как надо, но в железе не успевает. Можно ли как-то объяснить синтезатору, что тут нужно делать именно счетчики, а не регистры+сумматор+компаратор? Или смириться и привыкать вставлять мегафункции? А счетчик это и есть регистр + сумматор. Компаратор ставится когда идет проверка на максимальное значение. Например счетчик считает от 0 до 12. if (cnt = 12) then -- Когда счетчик досчитал до конца это сравнение и есть компаратор cnt <= (others => '0'); else cnt <= cnt + "1"; -- Иначе продолжим считать - это и есть сумматор end if; Хотие быстрый счетчик? 1. Используйте счетчик, который считает от 0 до 2**n -1, который обнуляется переполнением. if (rising_edge(clk)) then cnt <= cnt + "1"; end if; 2. Каскадируйте счетчики: например вместо счетчика считающего от 0 до 1023 вы делаете 2 счетчика считающих от 0 до 511. Первый счетчик на 511 такте выдает сигнал (сигнал выход регистра) разрешающий работу второму счетчику. if (rising_edge(clk)) then cnt <= cnt + "1"; if cnt = 511 then carry <= '1'; else carry <= '0'; end if; end if; Второй счетчик работает по сигналу разрешения первого счетчика вы формируете сигнал разрешения работы на регистре. if (rising_edge(clk)) then if carry = '1' then cnt <= cnt + "1"; end if; end if; 3. Атрибуты синтеза при правильном их применении могут творить чудеса: library altera; use altera.altera_syn_attributes.all; ... ... architecture rtl of top is attribute direct_enable of carry : signal is true; ... ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Avex 1 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба Если в железе не успевает, значит есть проблемы с таймингом, а значит тул пытается сократить задержки любой ценой, к примеру - если аппаратый счетчик находится далеко (геометрически) от интерфейсной логики этого блока, то тул может посчитать что быстрее будет реализация на простых регистрах. Вывод -если хотите получить именно аппаратные счетчики - вначале расслабьте частоту, и вы их увидите. А когда увидите, постарайтесь переписать дизайн (или просто по другому расставить выводы), чтобы тул и на высокой частоте продолжал их использовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 3 минуты назад, Aleх сказал: Если в железе не успевает, значит есть проблемы с таймингом, а значит тул пытается сократить задержки любой ценой, к примеру - если аппаратый счетчик находится далеко (геометрически) от интерфейсной логики этого блока, то тул может посчитать что быстрее будет реализация на простых регистрах. Вывод -если хотите получить именно аппаратные счетчики - вначале расслабьте частоту, и вы их увидите. А когда увидите, постарайтесь переписать дизайн (или просто по другому расставить выводы), чтобы тул и на высокой частоте продолжал их использовать. Разве в MaxII EPM570T100 есть примитивы готовых счетчиков ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 24 минуты назад, AltairNsk сказал: Привычно глазам, в симуляторе тикает как надо, но в железе не успевает. На самом деле, есть еще кое-что, что Вы нам не сообщили. 1. Разрядность счетчиков? При большой разрядности и высоким требованиям к частоте, компилятор попытается сделать счетчик с синхронным переносом, а для этого требуется много ресурсов. Хотя Вы можете вручную написать счетчик с параллельным переносом. И тогда все это увидите. 2. Если величины для сравнения: bit_cntmax и word_cntmax заданы не параметрами, а в регистрах, то это тоже жрет много ресурсов при большой разрядности счетчиков. И еще мне не понятно вот это: if (bit_cnt < bit_cntmax) bit_cnt <= bit_cnt + 1; else bit_cnt <= 0; Если bit_cnt < bit_cntmax не выполняется, то это значит, что bit_cnt == bit_cntmax. Тогда по "else bit_cnt <= 0;" Итак счетчик обнулился.. А как тогда будет выполняться следующая строка: if (bit_cnt == bit_cntmax) begin Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 9 минут назад, iosifk сказал: А как тогда будет выполняться следующая строка: Запросто. bit_cntmax — это максималньое значение счётчика. 47 минут назад, AltairNsk сказал: Добрый день Осваиваю плисоводство, на плате MaxII EPM570T100, соответственно quartus 13.0sp1 webedition. Нарисовалась вот такая штука, три вложенных счетчика с параметрами, задающих времянки //input bit_cntmax, word_cntmax if (bit_cnt < bit_cntmax) bit_cnt <= bit_cnt + 1; else bit_cnt <= 0; if (bit_cnt == bit_cntmax) begin if (word_cnt < word_cntmax) word_cnt <= word_cnt + 1; else word_cnt <= 0; end if (bit_cnt == bit_cntmax && word_cnt == word_cntmax) begin if (msg_cnt < MSG_LENGTH) msg_cnt <= msg_cnt + 1; else msg_cnt <= 0; end //output sig = f(bit_cnt, word_cnt, msg_cnt) Если ваши *_cntmax не меняются в процессе счёта, ну то есть задали *_cntmax, запустили счёт, досчитали, задали новые, то замените сравнени "меньше" на "не равно". При счёте с шагом 1 вы через эти значения не перескочите. 40 минут назад, Flip-fl0p сказал: А счетчик это и есть регистр + сумматор. Компаратор ставится когда идет проверка на максимальное значение. Ну гругря да, в RTL так и выглядит. Но вообще говоря синтез счётчиков делается немного по-другому: с таблицами переходов, диаграммами Вейча или картами Карно и т. п.: https://radioaktiv.ru/publ/lessons/digitall/132-publ_70.html. Понятно, что сейчас всё это делает синтезатор с учётом того, какие примитивы есть в целевой ПЛИС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 3 минуты назад, andrew_b сказал: Запросто. bit_cntmax — это максималньое значение счётчика. Еще раз медленно... Если (bit_cnt < bit_cntmax), то это выполняется, то счетчик инкрементируется. Так? А если не выполняется т.е. это значит, что bit_cnt == bit_cntmax , то срабатывает "else bit_cnt <= 0;" И все... Больше нигде не будет выполняться условие того, что bit_cnt == bit_cntmax. А это и значит, что следующий "if (bit_cnt == bit_cntmax) begin" никогда не выполнится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 32 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 10 minutes ago, iosifk said: Еще раз медленно... ... А это и значит, что следующий "if (bit_cnt == bit_cntmax) begin" никогда не выполнится. Это шутка такая? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 22 минуты назад, andrew_b сказал: Запросто. bit_cntmax — это максималньое значение счётчика. Ну гругря да, в RTL так и выглядит. Но вообще говоря синтез счётчиков делается немного по-другому: с таблицами переходов, диаграммами Вейча или картами Карно и т. п.: https://radioaktiv.ru/publ/lessons/digitall/132-publ_70.html. Понятно, что сейчас всё это делает синтезатор с учётом того, какие примитивы есть в целевой ПЛИС. Ну естественно в цифровой схемотехнике все так и делается. Даже у нас Лабораторные были в университете про синтез счетчиков, с различными видами переносов. Там много различных методик построения счетчиков есть. Но применительно к ПЛИС - синтезатор лепит счетчики из того что есть. А это регистры + лут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltairNsk 0 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 21 minutes ago, iosifk said: На самом деле, есть еще кое-что, что Вы нам не сообщили. bit_cnt[11:0], word_cnt[3:0], msg_cnt[6:0]; *_cntmax - регистры, значения загружаются перед счетом 39 minutes ago, iosifk said: Если bit_cnt < bit_cntmax не выполняется, то это значит, что bit_cnt == bit_cntmax. Тогда по "else bit_cnt <= 0;" Итак счетчик обнулился.. А как тогда будет выполняться следующая строка: if (bit_cnt == bit_cntmax) begin как-то так always @(posedge clk, posedge rst) begin if (rst) begin bit_cnt <= 0; end else begin if (bit_cnt < bit_cntmax) bit_cnt <= bit_cnt + 1; else bit_cnt <= 0; end end 36 minutes ago, iosifk said: Хотя Вы можете вручную написать счетчик с параллельным переносом. Вот от ручного написания хотелось бы уйти. Точнее понять, где заканчивается интеллектуальность компилятора и только руками. 7 minutes ago, Flip-fl0p said: Но применительно к ПЛИС - синтезатор лепит счетчики из того что есть. А это регистры + лут. Поглядел что делает megawizard plugin. Похоже, вяжет цепочку LABов по канонам счетчикостроения и оно тикает, если cnt_en. Когда q==bit_cntmax, дёрнуть sclr. От сумматора избавляюсь, верно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 32 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 1 hour ago, AltairNsk said: Привычно глазам, в симуляторе тикает как надо, но в железе не успевает. А частота то какая? И спид-грейд девайса тоже важен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 1 час назад, AltairNsk сказал: но в железе не успевает. А о какой частоте идет речь? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltairNsk 0 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 6 minutes ago, blackfin said: А частота то какая? И спид-грейд девайса тоже важен. 100 МГц, EPM570T100C5 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
blackfin 32 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 12 minutes ago, AltairNsk said: 100 МГц, EPM570T100C5 Не удивительно. Попробуйте так: reg bit_cnt_fire = 0; always @(posedge ...) begin if (bit_cnt < bit_cntmax) bit_cnt <= bit_cnt + 1; else bit_cnt <= 0; bit_cnt_fire <= (bit_cnt == bit_cntmax - 1); if (bit_cnt_fire) begin if (word_cnt < word_cntmax) word_cnt <= word_cnt + 1; else word_cnt <= 0; end if (bit_cnt_fire && word_cnt == word_cntmax) begin if (msg_cnt < MSG_LENGTH) msg_cnt <= msg_cnt + 1; else msg_cnt <= 0; end end Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zig 39 5 апреля, 2020 Опубликовано 5 апреля, 2020 · Жалоба 57 минут назад, AltairNsk сказал: *_cntmax - регистры, значения загружаются перед счетом Если вам нужно считать до разных значений, то для времянок будет лучше сделать счетчик считающий вниз. Сравнение будет всегда с нулем (или единицей), а загружаться счетчик должен вашим *_cntmax-1 (или *_cntmax). Сравнение с нулем в структуре ПЛИС реализуется на схемах ускоренного переноса и будет работать существенно быстрее многоразрядного компаратора с произвольным значением. Применив такой способ вы выведите из состава счетчика компаратор на произвольное значение и времянка улучшится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться