Перейти к содержанию
    

Асинхронка в verilog

Всем привет!

Написал FSM разделив синхронку и асинхронку; то есть в одном always блоке синхронный процесс, во втором в списке чувствительности занесены все входные сигналы; Vivado 16.3 и 17.1 развели написанное мной ядро так, что сигналы из списка чувствительности воспринимаются как не законстрэйнченые клоки... Вопрос - это нормално и можно на это забить? Или где-то в коде косяк и такого не должно быть?

Что бы было понятнее про что я - я прикрепляю фотку (принсткрин сделать не могу сейчас, прошу прощения за качество)

IMG-20170702-_WA0005_1.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Асинхронные сигналы в FSM использовать вообще нельзя, надо их синхронизировать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Асинхронные сигналы в FSM использовать вообще нельзя, надо их синхронизировать.

я про state/prestate

http://www.asic-world.com/tidbits/verilog_fsm.html "Using Two Always Blocks"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Написал FSM разделив синхронку и асинхронку; то есть в одном always блоке синхронный процесс, во втором в списке чувствительности занесены все входные сигналы;

Неправильно написанное вызывает неправильные ответы и недоумение...

В FSM есть две части: комбинационная и последовательностная (регистровая) логика. При этом комбинационная логика сама по себе тоже должна порождаться от регистров и комбинационных схем, т.е. быть синхронной.

А вот входные сигналы, если они асинхронные, то они должны быть засинхронизированы с клоком FSM.

И зачем нам Ваши мутные фотки? Ведь есть такая вещь как скрин-шот...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Неправильно написанное вызывает неправильные ответы и недоумение...

В FSM есть две части: комбинационная и последовательностная (регистровая) логика. При этом комбинационная логика сама по себе тоже должна порождаться от регистров и комбинационных схем, т.е. быть синхронной.

А вот входные сигналы, если они асинхронные, то они должны быть засинхронизированы с клоком FSM.

И зачем нам Ваши мутные фотки? Ведь есть такая вещь как скрин-шот...

 

Мутные фотки это все что было на момент написания поста - у меня не было доступа к компьютеру, а фото мне прислали.

Я повторю вопрос конкретнее, это моя ошибка, что сформулировал не достаточно точно - Нормальна ли ситуация, что сигнали из списка чувствительности процесса интерпретировались как незаконстрейнченые клоки и можно ли просто проигнорировать этот факт? или это сигнализирует о некорректном описании в rtl?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нормальна ли ситуация, что сигнали из списка чувствительности процесса интерпретировались как незаконстрейнченые клоки и можно ли просто проигнорировать этот факт? или это сигнализирует о некорректном описании в rtl?

А латчей вы там случаем не наплодили по неопытности? Отсюда и "клоки"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скорее всего это 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
   );

Мне было не очевидно, что на самом деле это не так

Сейчас уже вижу, что приоритеты ресета в двух кусках разные

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем вы мучаетесь сами и мучаете других подобным стилем кодирования?

Разве не проще что-то вроде:

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

Изменено пользователем 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

Вы про какой стиль? Вы привели пример описания конечного автомата, а я - описания асинхронного латча. Проблемы с сигналами fsm возникли из-за того, что я не правильно описал латч... С учетом того, что мой конечный автомат реализован по методу, который вы и описали, я Вас не понял.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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, если не определить все состояния, появятся латчи. Чтобы этого не произошло, надо определить состояние по "умолчанию"...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На самом деле в любом case, если не определить все состояния, появятся латчи. Чтобы этого не произошло, надо определить состояние по "умолчанию"...

В моем примере else разве не определяет состояния "по умолчанию"? Если речь идет об fsm, то там default поле, естественно, есть

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В моем примере else разве не определяет состояния "по умолчанию"? Если речь идет об fsm, то там default поле, естественно, есть

Я не внимательно вчитался в Ваш код, наверное потому и не понял...

Просто я так никогда не делаю:

always @(*) begin

if (header_formatter_ready)

header_formatter_ready_latch....

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не внимательно вчитался в Ваш код, наверное потому и не понял...

Просто я так никогда не делаю:

always @(*) begin

if (header_formatter_ready)

header_formatter_ready_latch....

 

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

Просто пока автомат крутился в ряде начальных состояний мог прийти импульс, а информация о том приходил ли он понадобилась бы лишь в конце, я посчитал, что вместо вставляния этого детектирования во все начальные состояния, проще сделать отдельный латч. Можно было бы сделать синхронное детектирование по клоку, но разве это принципиально?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто пока автомат крутился в ряде начальных состояний мог прийти импульс, а информация о том приходил ли он понадобилась бы лишь в конце, я посчитал, что вместо вставляния этого детектирования во все начальные состояния, проще сделать отдельный латч. Можно было бы сделать синхронное детектирование по клоку, но разве это принципиально?

Если приходит асинхронный сигнал, то необходимо привязать его к клоку...

И моя позиция такая. Не плодить множество мелких триггеров, а делать наборы автоматов.

Скажем так для примера как в SPI: нижний фильтрует помеху и принимает биты и больше ничего не умеет. Результат передает "вверх" "среднему" по своему выходу "Готов"... "Средний" умеет только принимать слова. Результат передает "вверх" "верхнему" по своему выходу "Готов".. А "верхний" умеет принимать сообщения и класть их в память, например... Он знает куда класть и кому об этом сообщить... И выше всех сидит автомат, который ведет весь процесс. За ним - верхние уровни протокола и пр...

Полное разделение труда...

При таком подходе все становится просто до безобразия...

А компилятор потом сам произведет оптимизацию и уберет все лишнее...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...