e HVL (IEEE 1647): выражение ожидания неожиданно завершается ошибкой

Я пытаюсь проверить довольно простое рукопожатие между двумя модулями. Один модуль находится на медленных часах и поднимает «req», более быстрый модуль должен поднимать «ack» на следующих быстрых часах и удерживать его до следующего позирования медленных часов. Конечный результат выглядит так:

пример волновой диаграммы запроса

Вот как я написал ожидание:

expect expect_ack_when_req_go is
      (@req_rise_e) => @ack_rise_e
      else dut_error("ERROR: ack expected to be asserted when req rises!");

*оба @req_rise_e и @ack_rise_e сэмплируются на медленных тактовых частотах.

Запуск симулятора приводит к ошибке, поскольку первое выражение кажется успешным, а второе - нет. И это несмотря на то, что при отслеживании событий в волне я вижу, что оба события происходят вместе (как видно в волне: event_req, event_ack).


person Shay Golan    schedule 25.09.2017    source источник
comment
Я бы сначала попробовал добавить в TE часы выборки, т.е. expect ... (@req_rise_e => @ack_rise_e)@slow_clk;   -  person Thorsten    schedule 26.09.2017
comment
Уже пробовал, и ничего хорошего... Кроме того, я думаю, что это избыточно, так как оба события уже отсемплированы медленными часами: event req_rise_e is rise (smp.port_req$) @slow_clk_e; event ack_rise_e is rise (smp.port_ack$) @slow_clk_e;   -  person Shay Golan    schedule 26.09.2017
comment
Хорошо, @Thorsten, похоже, ты был прав! Похоже, что добавление тактовой частоты дискретизации к обоим сигналам вместе меняет что-то в том, как симулятор понимает проверочное выражение. Я изменил его так, как вы предложили, и это сработало ... Хотя я не могу это объяснить ... Если вы можете это понять, возможно, вам следует опубликовать это как решение?   -  person Shay Golan    schedule 26.09.2017
comment
Исправление: @Thorsten, кажется, вы были частично правы! Сначала я изменил ack_event на true (ack$ == 1), а не на повышение (ack$). Это все еще не работало, но как только я добавил часы сэмплирования так, как вы предложили, это решило проблему. Хотя я до сих пор не могу этого объяснить.   -  person Shay Golan    schedule 26.09.2017
comment
Еще одна мысль: ack меняется дважды в течение slow_clk периода, возможно, это проблема, решаемая с помощью порта событий. Не могли бы вы изменить smp.port_ack на порт событий, который срабатывает при повышении?   -  person Thorsten    schedule 26.09.2017


Ответы (1)


Вы пытаетесь сделать перекрывающиеся последствия, то есть оба ваших события происходят в одном и том же цикле. Что делает оператор =>, так это проверяет, что следствие происходит при следующем событии выборки, в данном случае при следующем медленном фронте тактового сигнала. На языке утверждений SystemVerilog это называется неперекрывающейся импликацией.

Вы можете получить желаемое поведение, написав следующее:

expect expect_ack_when_req_go is
  (@req_rise_e) => detach({@ack_rise_e; ~[1]})
  else dut_error("ERROR: ack expected to be asserted when req rises!");

Полное объяснение здесь.

С методологической точки зрения я бы рекомендовал не писать временное выражение по-другому. Я предполагаю, что вы проверяете модуль, управляющий ack, и этот модуль работает на обоих часах. Я бы также предположил, что этот модуль сэмплирует req с быстрыми часами. Было бы понятнее сформулировать ваш чек так:

expect expect_ack_when_req_go is
  (@req_rise_at_fast_clock_e) => @ack_rise_at_slow_clock_e
  else dut_error("ERROR: ack expected to be asserted when req rises!");

Таким образом, вам не нужно возиться с detach(...), а expect более точно соответствует естественному языку описания желаемого поведения.

person Tudor Timi    schedule 26.09.2017
comment
Хорошо, отличный ответ! Я смутно помнил, что в SVA есть два импликационных оператора, но я давно не имел дело с кодом SystemVerilog. Также хорошее техническое объяснение в вашем блоге. Кроме того, вы также правы в методологическом отношении, и это исправление, которое я сделаю. СПАСИБО. - person Shay Golan; 27.09.2017