Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Асинхронка в verilog
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Языки проектирования на ПЛИС (FPGA)
Lutovid
Всем привет!
Написал FSM разделив синхронку и асинхронку; то есть в одном always блоке синхронный процесс, во втором в списке чувствительности занесены все входные сигналы; Vivado 16.3 и 17.1 развели написанное мной ядро так, что сигналы из списка чувствительности воспринимаются как не законстрэйнченые клоки... Вопрос - это нормално и можно на это забить? Или где-то в коде косяк и такого не должно быть?
Что бы было понятнее про что я - я прикрепляю фотку (принсткрин сделать не могу сейчас, прошу прощения за качество)
Timmy
Асинхронные сигналы в FSM использовать вообще нельзя, надо их синхронизировать.
Lutovid
Цитата(Timmy @ Jul 2 2017, 20:07) *
Асинхронные сигналы в FSM использовать вообще нельзя, надо их синхронизировать.

я про state/prestate
http://www.asic-world.com/tidbits/verilog_fsm.html "Using Two Always Blocks"
iosifk
Цитата(Lutovid @ Jul 2 2017, 19:43) *
Написал FSM разделив синхронку и асинхронку; то есть в одном always блоке синхронный процесс, во втором в списке чувствительности занесены все входные сигналы;

Неправильно написанное вызывает неправильные ответы и недоумение...
В FSM есть две части: комбинационная и последовательностная (регистровая) логика. При этом комбинационная логика сама по себе тоже должна порождаться от регистров и комбинационных схем, т.е. быть синхронной.
А вот входные сигналы, если они асинхронные, то они должны быть засинхронизированы с клоком FSM.
И зачем нам Ваши мутные фотки? Ведь есть такая вещь как скрин-шот...
Lutovid
Цитата(iosifk @ Jul 2 2017, 23:34) *
Неправильно написанное вызывает неправильные ответы и недоумение...
В FSM есть две части: комбинационная и последовательностная (регистровая) логика. При этом комбинационная логика сама по себе тоже должна порождаться от регистров и комбинационных схем, т.е. быть синхронной.
А вот входные сигналы, если они асинхронные, то они должны быть засинхронизированы с клоком FSM.
И зачем нам Ваши мутные фотки? Ведь есть такая вещь как скрин-шот...


Мутные фотки это все что было на момент написания поста - у меня не было доступа к компьютеру, а фото мне прислали.
Я повторю вопрос конкретнее, это моя ошибка, что сформулировал не достаточно точно - Нормальна ли ситуация, что сигнали из списка чувствительности процесса интерпретировались как незаконстрейнченые клоки и можно ли просто проигнорировать этот факт? или это сигнализирует о некорректном описании в rtl?
Bad0512
Цитата(Lutovid @ Jul 3 2017, 08:22) *
Нормальна ли ситуация, что сигнали из списка чувствительности процесса интерпретировались как незаконстрейнченые клоки и можно ли просто проигнорировать этот факт? или это сигнализирует о некорректном описании в rtl?

А латчей вы там случаем не наплодили по неопытности? Отсюда и "клоки"...
masics
Скорее всего это latches.
Lutovid
Цитата(masics @ Jul 3 2017, 12:26) *
Скорее всего это 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
Зачем вы мучаетесь сами и мучаете других подобным стилем кодирования?
Разве не проще что-то вроде:
Код
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
Lutovid
Цитата(one_eight_seven @ Jul 3 2017, 16:08) *
Зачем вы мучаетесь сами и мучаете других подобным стилем кодирования?
Разве не проще что-то вроде:
Код
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
Цитата(Lutovid @ Jul 3 2017, 15:55) *
Код
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
Цитата(iosifk @ Jul 3 2017, 16:45) *
На самом деле в любом case, если не определить все состояния, появятся латчи. Чтобы этого не произошло, надо определить состояние по "умолчанию"...

В моем примере else разве не определяет состояния "по умолчанию"? Если речь идет об fsm, то там default поле, естественно, есть
iosifk
Цитата(Lutovid @ Jul 3 2017, 16:46) *
В моем примере else разве не определяет состояния "по умолчанию"? Если речь идет об fsm, то там default поле, естественно, есть

Я не внимательно вчитался в Ваш код, наверное потому и не понял...
Просто я так никогда не делаю:
always @(*) begin
if (header_formatter_ready)
header_formatter_ready_latch....

Если у Вас есть автомат, то зачем вот это always @(*) ? У Вас что, какие-то сигналы могут меняться "между фронтами клоков"? В любом случае, должен быть автомат, который определяет, кому и когда что можно делать. И должны быть регистры, счетчики и все прочее, которые получают от автомата сигналы на разрешение записи, сдвига, обнуления и т.д.
Lutovid
Цитата(iosifk @ Jul 3 2017, 16:59) *
Я не внимательно вчитался в Ваш код, наверное потому и не понял...
Просто я так никогда не делаю:
always @(*) begin
if (header_formatter_ready)
header_formatter_ready_latch....

Если у Вас есть автомат, то зачем вот это always @(*) ? У Вас что, какие-то сигналы могут меняться "между фронтами клоков"? В любом случае, должен быть автомат, который определяет, кому и когда что можно делать. И должны быть регистры, счетчики и все прочее, которые получают от автомата сигналы на разрешение записи, сдвига, обнуления и т.д.

Просто пока автомат крутился в ряде начальных состояний мог прийти импульс, а информация о том приходил ли он понадобилась бы лишь в конце, я посчитал, что вместо вставляния этого детектирования во все начальные состояния, проще сделать отдельный латч. Можно было бы сделать синхронное детектирование по клоку, но разве это принципиально?
iosifk
Цитата(Lutovid @ Jul 3 2017, 17:08) *
Просто пока автомат крутился в ряде начальных состояний мог прийти импульс, а информация о том приходил ли он понадобилась бы лишь в конце, я посчитал, что вместо вставляния этого детектирования во все начальные состояния, проще сделать отдельный латч. Можно было бы сделать синхронное детектирование по клоку, но разве это принципиально?

Если приходит асинхронный сигнал, то необходимо привязать его к клоку...
И моя позиция такая. Не плодить множество мелких триггеров, а делать наборы автоматов.
Скажем так для примера как в SPI: нижний фильтрует помеху и принимает биты и больше ничего не умеет. Результат передает "вверх" "среднему" по своему выходу "Готов"... "Средний" умеет только принимать слова. Результат передает "вверх" "верхнему" по своему выходу "Готов".. А "верхний" умеет принимать сообщения и класть их в память, например... Он знает куда класть и кому об этом сообщить... И выше всех сидит автомат, который ведет весь процесс. За ним - верхние уровни протокола и пр...
Полное разделение труда...
При таком подходе все становится просто до безобразия...
А компилятор потом сам произведет оптимизацию и уберет все лишнее...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.