Вопрос о срабатывании всегда блоков - PullRequest
1 голос
/ 28 марта 2019

Я знаю, что блок всегда будет срабатывать при изменении любого из элементов в своем списке чувствительности, однако, мой вопрос: что произойдет, если произойдет изменение в списке чувствительности, когда операторы внутри блоков всегда будут выполняться ( из-за предыдущего триггера). Блок Always всегда начинает выполнение в параллельном потоке или блокирует запуск до тех пор, пока выполнение не завершится первым?

Ответы [ 3 ]

2 голосов
/ 28 марта 2019

Многие люди не понимают, что @ является модификатором оператора, а не конструируется сам по себе. В нем говорится отложить утверждение, которое следует, до тех пор, пока не произойдет событие. @(A or B) означает ожидание, пока не произойдет изменение значения A или B (не путать с изменением результата A | B). @* означает, что посмотрите на следующее утверждение и создайте неявный список чувствительности для ожидания изменения.

always @(A or B) C = A + B;
always begin
         @(A or B) C = A + B;
       end
always begin
         @* C = A + B;
       end
always_comb
       begin
         C = A + B;
       end

Эти 4 always блоки имеют идентичное поведение, за исключением последнего always_comb также запускаются в момент времени 0 независимо от каких-либо изменений в A или B.

Если вы посмотрите на код, который следует за always как процедурную последовательность выполнения операторов, может быть проще увидеть конструкцию @ как часть этой процедурной последовательности, и изменение должно произойти, пока вы выполнение конструкции. Простое добавление еще одной задержки покажет эту концепцию (не синтезируемую)

always @(A or B) begin
         #10 C = A + B;
       end

Здесь написано «дождитесь изменения A или B, затем подождите еще 10 единиц времени, затем сделайте присваивание C с текущими значениями A + B». Если A или B изменяются в течение 10-секундного периода ожидания, это изменение пропускается. Вы должны ждать другого изменения на А или В после этих 10 единиц времени.

1 голос
/ 28 марта 2019

Как только будет запущен всегда блок, он будет выполняться с начала до конца. Verilog - это однопоточное средство моделирования, поэтому одновременно может выполняться только один блок. Ничего другого не может произойти, пока выполняется блок Always, если только он не содержит операторов задержки или ожидания событий. В последнем случае это просто даст чтобы разрешить выполнение других блоков, затем он продолжается.

Если блок всегда изменяет свои входные данные к концу выполнения, то следующее поведение симуляции зависит от типа блока:

  • все блоки v95 / v2k всегда (например, всегда @ *) будут повторно запущены,
  • системные блоки verilog (например, always_comb) будут не повторно запускаться в текущем дельта-цикле.

С блоками v2k / v95 вы всегда можете получить цикл с нулевой задержкой, если не будете осторожны. Другими словами, симуляция может зависнуть.

С блоками SystemVerilog вы можете получить интересное условие «чтение перед записью» (когда переменная читается до того, как она записана в том же блоке). Это может потенциально привести к несоответствию симуляции / синтеза.

1 голос
/ 28 марта 2019

Каждый блок всегда является одним потоком (если он не содержит fork - join).Таким образом, если он выполняется, он не будет повторно запускаться, если что-то в списке чувствительности изменяется.(Если он содержит fork - join, то после запуска он разделяется на несколько потоков, но снова не запускается).

...