Lutovid 1 2 июля, 2017 Опубликовано 2 июля, 2017 · Жалоба Всем привет! Написал FSM разделив синхронку и асинхронку; то есть в одном always блоке синхронный процесс, во втором в списке чувствительности занесены все входные сигналы; Vivado 16.3 и 17.1 развели написанное мной ядро так, что сигналы из списка чувствительности воспринимаются как не законстрэйнченые клоки... Вопрос - это нормално и можно на это забить? Или где-то в коде косяк и такого не должно быть? Что бы было понятнее про что я - я прикрепляю фотку (принсткрин сделать не могу сейчас, прошу прощения за качество) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 2 июля, 2017 Опубликовано 2 июля, 2017 · Жалоба Асинхронные сигналы в FSM использовать вообще нельзя, надо их синхронизировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lutovid 1 2 июля, 2017 Опубликовано 2 июля, 2017 · Жалоба Асинхронные сигналы в FSM использовать вообще нельзя, надо их синхронизировать. я про state/prestate http://www.asic-world.com/tidbits/verilog_fsm.html "Using Two Always Blocks" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 2 июля, 2017 Опубликовано 2 июля, 2017 · Жалоба Написал FSM разделив синхронку и асинхронку; то есть в одном always блоке синхронный процесс, во втором в списке чувствительности занесены все входные сигналы; Неправильно написанное вызывает неправильные ответы и недоумение... В FSM есть две части: комбинационная и последовательностная (регистровая) логика. При этом комбинационная логика сама по себе тоже должна порождаться от регистров и комбинационных схем, т.е. быть синхронной. А вот входные сигналы, если они асинхронные, то они должны быть засинхронизированы с клоком FSM. И зачем нам Ваши мутные фотки? Ведь есть такая вещь как скрин-шот... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lutovid 1 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Неправильно написанное вызывает неправильные ответы и недоумение... В FSM есть две части: комбинационная и последовательностная (регистровая) логика. При этом комбинационная логика сама по себе тоже должна порождаться от регистров и комбинационных схем, т.е. быть синхронной. А вот входные сигналы, если они асинхронные, то они должны быть засинхронизированы с клоком FSM. И зачем нам Ваши мутные фотки? Ведь есть такая вещь как скрин-шот... Мутные фотки это все что было на момент написания поста - у меня не было доступа к компьютеру, а фото мне прислали. Я повторю вопрос конкретнее, это моя ошибка, что сформулировал не достаточно точно - Нормальна ли ситуация, что сигнали из списка чувствительности процесса интерпретировались как незаконстрейнченые клоки и можно ли просто проигнорировать этот факт? или это сигнализирует о некорректном описании в rtl? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bad0512 2 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Нормальна ли ситуация, что сигнали из списка чувствительности процесса интерпретировались как незаконстрейнченые клоки и можно ли просто проигнорировать этот факт? или это сигнализирует о некорректном описании в rtl? А латчей вы там случаем не наплодили по неопытности? Отсюда и "клоки"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
masics 0 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Скорее всего это latches. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lutovid 1 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Скорее всего это latches. Вы праввы Я посчитал, что вот это always @(*) begin if (header_formatter_ready) header_formatter_ready_latch <= 1'b1; else if (ascii_header_dataout_rd_en || reset_header_config) header_formatter_ready_latch <= 1'b0; else header_formatter_ready_latch <= header_formatter_ready_latch; end синтезируется как LDCE LDCE #( .INIT(1'b0) // Initial value of latch (1'b0 or 1'b1) ) LDCE_inst ( .Q(header_formatter_ready_latch), // Data output .CLR(ascii_header_dataout_rd_en || reset_header_config), // Asynchronous clear/reset input .D(1'b1), // Data input .G(1'b1), // Gate input .GE(header_formatter_ready) // Gate enable input ); Мне было не очевидно, что на самом деле это не так Сейчас уже вижу, что приоритеты ресета в двух кусках разные Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
one_eight_seven 6 3 июля, 2017 Опубликовано 3 июля, 2017 (изменено) · Жалоба Зачем вы мучаетесь сами и мучаете других подобным стилем кодирования? Разве не проще что-то вроде: always @(posedge clk or negedge async_rst_n) begin : sequential_code if (!async_rst_n) state <= { WIDTH {1'b0}}; else state <= nextstate; end always @* begin : comb_block nextstate = state; // store current state for loopbacks case (state) STATE0 : begin if (go_state_1) nextstate = STATE1; else if (go_state_2) nextstate = STATE2; ... end ... endcase end Изменено 3 июля, 2017 пользователем one_eight_seven Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lutovid 1 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Зачем вы мучаетесь сами и мучаете других подобным стилем кодирования? Разве не проще что-то вроде: always @(posedge clk or negedge async_rst_n) begin : sequential_code if (!async_rst_n) state <= { WIDTH {1'b0}}; else state <= nextstate; end always @* begin : comb_block nextstate = state; // store current state for loopbacks case (state) STATE0 : begin if (go_state_1) nextstate = STATE1; else if (go_state_2) nextstate = STATE2; ... end ... endcase end Вы про какой стиль? Вы привели пример описания конечного автомата, а я - описания асинхронного латча. Проблемы с сигналами fsm возникли из-за того, что я не правильно описал латч... С учетом того, что мой конечный автомат реализован по методу, который вы и описали, я Вас не понял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба always @(*) begin if (header_formatter_ready) header_formatter_ready_latch <= 1'b1; else if (ascii_header_dataout_rd_en || reset_header_config) header_formatter_ready_latch <= 1'b0; else header_formatter_ready_latch <= header_formatter_ready_latch; end синтезируется как LDCE Мне было не очевидно, что на самом деле это не так Сейчас уже вижу, что приоритеты ресета в двух кусках разные На самом деле в любом case, если не определить все состояния, появятся латчи. Чтобы этого не произошло, надо определить состояние по "умолчанию"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lutovid 1 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба На самом деле в любом case, если не определить все состояния, появятся латчи. Чтобы этого не произошло, надо определить состояние по "умолчанию"... В моем примере else разве не определяет состояния "по умолчанию"? Если речь идет об fsm, то там default поле, естественно, есть Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба В моем примере else разве не определяет состояния "по умолчанию"? Если речь идет об fsm, то там default поле, естественно, есть Я не внимательно вчитался в Ваш код, наверное потому и не понял... Просто я так никогда не делаю: always @(*) begin if (header_formatter_ready) header_formatter_ready_latch.... Если у Вас есть автомат, то зачем вот это always @(*) ? У Вас что, какие-то сигналы могут меняться "между фронтами клоков"? В любом случае, должен быть автомат, который определяет, кому и когда что можно делать. И должны быть регистры, счетчики и все прочее, которые получают от автомата сигналы на разрешение записи, сдвига, обнуления и т.д. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lutovid 1 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Я не внимательно вчитался в Ваш код, наверное потому и не понял... Просто я так никогда не делаю: always @(*) begin if (header_formatter_ready) header_formatter_ready_latch.... Если у Вас есть автомат, то зачем вот это always @(*) ? У Вас что, какие-то сигналы могут меняться "между фронтами клоков"? В любом случае, должен быть автомат, который определяет, кому и когда что можно делать. И должны быть регистры, счетчики и все прочее, которые получают от автомата сигналы на разрешение записи, сдвига, обнуления и т.д. Просто пока автомат крутился в ряде начальных состояний мог прийти импульс, а информация о том приходил ли он понадобилась бы лишь в конце, я посчитал, что вместо вставляния этого детектирования во все начальные состояния, проще сделать отдельный латч. Можно было бы сделать синхронное детектирование по клоку, но разве это принципиально? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 3 июля, 2017 Опубликовано 3 июля, 2017 · Жалоба Просто пока автомат крутился в ряде начальных состояний мог прийти импульс, а информация о том приходил ли он понадобилась бы лишь в конце, я посчитал, что вместо вставляния этого детектирования во все начальные состояния, проще сделать отдельный латч. Можно было бы сделать синхронное детектирование по клоку, но разве это принципиально? Если приходит асинхронный сигнал, то необходимо привязать его к клоку... И моя позиция такая. Не плодить множество мелких триггеров, а делать наборы автоматов. Скажем так для примера как в SPI: нижний фильтрует помеху и принимает биты и больше ничего не умеет. Результат передает "вверх" "среднему" по своему выходу "Готов"... "Средний" умеет только принимать слова. Результат передает "вверх" "верхнему" по своему выходу "Готов".. А "верхний" умеет принимать сообщения и класть их в память, например... Он знает куда класть и кому об этом сообщить... И выше всех сидит автомат, который ведет весь процесс. За ним - верхние уровни протокола и пр... Полное разделение труда... При таком подходе все становится просто до безобразия... А компилятор потом сам произведет оптимизацию и уберет все лишнее... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться