bmv89 0 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба 2 часа назад, Джеймс сказал: Ну и в каком случае вы говорили то, что соответствует действительности? В обоих. С чего взяли, что одно другое исключает? Пробовал делать со сбросом от 44 пина в синхронном варианте (медленном), когда он был ещё не работоспособен. Затем методом тыка подобрал вариант (увидел на ютуб канале Jack0v) детектора фронтов с которым заработало. В конечном варианте асинхронный сброс уже не использовал, потому что и без него норм. Сейчас пытаюсь сделать асинхронный (быстрый) SPI, вообще не зависящий от i_core_clk, тактируемый spi клоком. 6 часов назад, Nick_K сказал: Зачем всё лепить в одном процессе? Сложно вынести txsw и counter в один процесс, а spirx и txbuf в другой Каюсь, с первого раза не усвоил дельный совет)) Действительно разные схемы в итоге синтезируются! Спасибо, что ткнули носом, куда надо)) Приём стал на много лучше, но всё ещё периодически проскакивают артефакты. module spi_slave( input wire SS, input wire SCLK, output wire MISO, input wire MOSI, output reg [7:0]spirx, input wire [7:0]spitx ); reg [7:0]txbuf; reg [7:0]spireg; reg txsw; reg [2:0]counter; always @(negedge SCLK or posedge SS) begin if(SS) begin txsw <= 1'b0; counter <= 3'd0; end else begin txsw <= 1'b1; counter <= counter + 1'd1; end end always @(negedge SCLK) begin if(counter == 3'd7) spirx <= spireg; if(counter == 3'd7 || ~txsw) txbuf <= spitx; end always @(posedge SCLK) begin spireg <= {spireg[6:0], MOSI}; end assign miso_mux = (txsw) ? txbuf[3'd7-counter] : spitx[3'd7-counter]; assign MISO = (~SS) ? miso_mux : 1'bz; endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 30 июня, 2020 Опубликовано 30 июня, 2020 (изменено) · Жалоба 15 hours ago, Nick_K said: Логично выглядит? Сейчас посмотрел, во что синтезируется подобный код(см. ниже), и погладил себя по головке - сам _никогда_ не использую асинхронный сброс. top( input clk, nclr, d, output reg q ); always@(posedge clk or negedge nclr) if(! nclr); else q<=d; endmodule Изменено 30 июня, 2020 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Raven 11 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба И что же такого страшного вы там могли увидеть? Триггер с асинхронным сбросом - это он вас так напугал? Хотя постойте, именно приведенный вами код действительно будет превращаться во что-то пострашнее - это же какой-то регистр-защелка, и он совсем без сброса де-факто! По nclr синтезатору нужно придумать, как сохранить предыдущее состояние. Поэтому и результат синтеза впечатляет. Только причем здесь асинхронный сброс? А вообще - это не должно быть догмой. В разных ситуациях по-разному: где-то лучше придерживаться синхронных сбросов, а в других - асинхронные имеют явные преимущества. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Plain 226 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба Триггер с асинхронным сбросом составляет основу типовой ячейки ПЛИС, т.е. он в готовом виде уже имеется безо всяких синтезирований. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба module top( input clk, nclr, d, output reg q ); always@(posedge clk or negedge nclr) q<=d; endmodule Очевидно? 11 minutes ago, Raven said: именно приведенный вами код Поправил, имел в виду обычное описание асинхронного сброса "if(! nclr)". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Raven 11 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба Поправьте до конца тогда уж. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба 1 minute ago, Raven said: Поправьте до конца тогда уж. Код для случая, когда какой-либо регистр пропущен в ветке "if(! nclr)", по ошибке или незнанию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Raven 11 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба 1 minute ago, Leka said: Код для случая, когда какой-либо регистр пропущен в ветке "if(! nclr)", по ошибке или незнанию. Для борьбы с ошибками или незнанием существуют штуки под названиями верификация, LINT check и даже более страшный equivalence check. Это не значит, что нужно только из-за этого лишать себя асинхронных сбросов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 30 июня, 2020 Опубликовано 30 июня, 2020 (изменено) · Жалоба Асинхронный сброс - это костыль. Противоречит здравой идее синхронного дизайна. Служит источником трудноуловимых ошибок. Замусоривает код. И тд и тп. Изменено 30 июня, 2020 пользователем Leka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Джеймс 4 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба 1 hour ago, Leka said: Сейчас посмотрел, во что синтезируется подобный код(см. ниже), и погладил себя по головке - сам _никогда_ не использую асинхронный сброс. @Leka Извините, вопрос совсем не по теме. А Вы "в команде" занимаетесь FPGA-разработкой или один? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Raven 11 30 июня, 2020 Опубликовано 30 июня, 2020 · Жалоба Не хочу вестись на очередной holywar. Отмечу только, что любая идея, доведенная до абсолюта, приводит, как правило, к плохим результатам. P.S. Немного не удержался все-таки: попробуйте задать начальные состояния своей логики в отсутствие тактового сигнала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 6 hours ago, Leka said: Асинхронный сброс - это костыль. Противоречит здравой идее синхронного дизайна. Служит источником трудноуловимых ошибок. Замусоривает код. И тд и тп. По секрету расскажу, в ПЛИС не бывает FF с синхронным сбросом в виде чистого примитива. В общем то как и в ASIC. Любое понятие "FF с синхронным сбросом" достигается путём дополнительной логики, которая делает оной (сброс) синхронным. Опять же, чем не угодил асинхронный сброс? Да он на такт раньше срабатывает. Да нужно понимать, что может не успеть сбросить. Но в основном то все сигналы включительно асинхронный сброс, формируются в синхронном домене. Тогда в чём проблема? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leka 1 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 2 hours ago, Nick_K said: Тогда в чём проблема? Проблема в том, когда _уходит_ асинхронный сброс. Из-за разных по кристаллу задержек относительно клока, в одной ячейке сигнал сброса может уйти раньше фронта клока, в другой - позже, и поведение уже не будет соответствовать описанию. 8 hours ago, Raven said: задать начальные состояния своей логики в отсутствие тактового сигнала. Тактовый сигнал отсутствует при включении питания, тогда куча процессов происходит - перевод GPIO в режим загрузки, загрузка прошивки, сброс всех регистров в начальное состояние (инициализация), ожидание захвата PLL, перевод GPIO в пользовательский режим, и только потом поведение соответствует коду. Так что в синхронном дизайне клок есть всегда, а начальное состояние регистров задается строками вида "reg [7:0] q = 8'd123" (и тп). 9 hours ago, Leka said: module top( input clk, nclr, d, output reg q ); always@(posedge clk or negedge nclr) q<=d; endmodule Попробуйте объяснить результат синтеза. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба 1 hour ago, Leka said: Проблема в том, когда _уходит_ асинхронный сброс. Из-за разных по кристаллу задержек относительно клока, в одной ячейке сигнал сброса может уйти раньше фронта клока, в другой - позже, и поведение уже не будет соответствовать описанию. Вы несёте какой-то бред. Ещё раз, сигнал для управления асинхронным сбросом формируется в синхронном домене (рассмотрим случай одного домена, без переходов). Timing Analysis в конце делает проверку, что все пути внутри этого синхронного домена соответствуют временным констрейнам, а это значит, что все формируемые сигналы (не важно установка или снятие сигнала) придёт от точки формирования до точки получения своевременно (без слэков). Ну или выдаст, что есть превышение RAT над AT, что в результате даст Slack. Единственная поправка для сигналлов асинхронного сброса - это значения setup и hold могут значительно отличаться от таковых в FF, о чём IDE прекрасно знает и учитывает. Таким образом, если в проекте нет отрицательных значений Slack, то как установка, так и снятие сигналлов, включительно сигналлы сброса и установки (синхронные и асинхронные - неважно), соответствуют заданным временным параметрам констрейнов и Violation'ов не будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bmv89 0 1 июля, 2020 Опубликовано 1 июля, 2020 · Жалоба Блин, все умными словами разговаривают такими))) Я с вашего разрешения напомню о своей проблеме? Если асинхронный сброс заставит мой асинхронный SPI работать в железе правильно, напишите пожалуйста куда и как его воткнуть. Пока видел только always @(posedge i_core_clk or negedge rst), i_core_clk здесь частота от генератора 50МГц. И ещё вопрос, есть разница от какого пина тактировать модуль? Если нет, то для чего у микросхемы есть специальные пины для подключения внешнего генератора (у EPM240T100C5 это PIN12, 14, 64, 62)? Если делать асинхронный SPI может имеет смысл подключать SPI CLK на один из этих выводов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться