2016-06-01 16 views
1

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

always_ff @ (posedge clk, negedge rst) 
begin 
    if (!rst) 
    a <= '0; 
end 

Если не факт, что всегда блок чувствителен к краю сигнала будет достаточно, чтобы сделать вывод, флип-флоп. В этом случае, когда срабатывает отрицательный фронт сброса, он получает 0, иначе он сохраняет прежнее значение.

Этот вопрос приходит от выбранного лучшего ответа от этого StackOverflow вопроса:
System Verilog always_latch vs. always_ff

========================== ======================================

Я расскажу, что я узнал до сих пор. Причина, по которой это синтезируется на защелку, вместо триггера, заключается в том, что в правой части задания есть константа. В этом случае поведение защелки и триггера EQUIVALENT, так как не имеет значения, поймает ли оно входное значение на краю сигнала (триггер) или когда блокировка входа включена (защелка) в качестве ввод не меняется. Поэтому инструмент синтеза выбирает элемент, который потребляет меньше ресурсов, то есть защелку.

С другой стороны, если в правой части задания была ПЕРЕМЕННАЯ, синтез должен был бы вывести триггер, , потому что было бы важно, будет ли диск дискретизирован на фронте (триггер) или во время блокировки входа включена (защелка), что означает, что два логических элемента НЕ ЭКВИВАЛЕНТЫ.

Вот пример. Первые два всегда блока будут синтезироваться на защелку (в Quartus 14), которая в порядке, так как они эквивалентны из-за константы. Но, 3. и 4. всегда блок будет также синтезирован в защелку, которая не является предполагаемым поведением, и эти блоки не эквивалентны! 3. блок выдаст предупреждение, а 4 - нет.

module ff_latch(
    input logic clk, 
    input logic nrst, 
    input logic a, 
    output logic t, x, y, z 
); 

    always_ff @(posedge clk, negedge nrst) 
     begin 
      if (!nrst) 
      t <= 0; 
     end 

    always_latch 
     begin 
      if (!nrst) 
      x <= 0; 
     end 

    always_ff @(posedge clk, negedge nrst) 
     begin 
      if (!nrst) 
      y <= a; 
     end 

    always_latch 
     begin 
      if (!nrst) 
      z <= a; 
     end 

endmodule: ff_latch 

Для меня такое поведение не является правильным, так как я специально сказал, что хочу флип-флоп (с краевым запуска). Это даже не о том, что кодирование является неоднозначным, всегда блоки 3. и 4. явно отличаются, как можно видеть в этой форме волны из приведенного выше моделирования:

enter image description here

Блок 3. (tb_y) ведет себя как асинхронный триггер и блок 4. (tb_z) ведет себя как защелка. Но инструмент синтеза имеет защелку в обоих случаях.

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

ответ

4

Синтезатор выберет защелку, потому что этот код ведет себя как защелка. Он не ведет себя как триггер. Это так просто.

Подумайте, как ведет себя этот код: изначально значение a будет 'x. Когда rst утверждается низким, то a станет '0. a будет оставаться на '0 навсегда. Следовательно, состояние a зависит не только от текущего состояния входов, но и от прошлого состояния.Поэтому мы имеем последовательная логика, а не комбинационная логика. Флип-флоп изменяет состояние на краю такта; a нет. Тот факт, что всегда блок чувствителен к краю сигнала, не имеет значения. Это просто означает, что код внутри выполнен на этом краю сигнала - положительный фронт clk. Но когда это происходит, ничего не происходит, поэтому этот код ведет себя как защелка.

+0

ОК, но мне кажется, что он также может вести себя как флип-флоп. При отрицательном сбросе сбросьте триггер, иначе на положительном фронте clk сохранится предыдущее значение. Это будет эквивалентно: [link] (http://imgur.com/htuPVsC) Кроме того, аппаратное обеспечение не может иметь состояние x. Это может быть 0, 1 или Z, поэтому в обоих случаях (защелка или триггер) он будет рассчитываться на какое-то произвольное значение при включении питания (0 или 1). Мне кажется, что код может вести себя как и то, и другое, но инструменты синтеза выбирают тот, который требует меньше ресурсов. – evilpascal

+0

@evilpascal Выбор схемы, которая потребляет меньше ресурсов, - это в значительной степени хлеб и масло для синтезатора. –

1

Потому что вы не указали, что происходит в posedge часов. Это как если бы a не зависит от clk или от его posedge. Все ваше описание гласит, что a установлен в 0, когда rst=0. Более того, он говорит (неявно), что a сохраняет свое предыдущее значение во всех остальных случаях. Это может быть реализовано защелкой.

Обратите внимание, что только потому, что у вас есть @posedge clk, не означает, что каждая переменная внутри этого блока будет синтезирована как флоп. Вам также необходимо неблокирующее присвоение a, когда блок активирован в posedge clk. См. here.

Если вы настаиваете на флопе, чтобы реализовать ту же функциональность, вы можете попробовать это:

always_ff @ (posedge clk or negedge rst) 
begin 
    if (!rst) 
    a <= '0; 
    else 
    a <= a; //Here, we are specifying what happens @posedge of clk 
end 
+0

Но первый код в моем сообщении должен вести себя как триггер с асинхронным сбросом, а не защелкой, поскольку он должен только пробовать на заднем фронте сброса, а не все время, когда сброс отменяется. Пожалуйста, посмотрите мой анализ в отредактированном вопросе. – evilpascal

+1

Какой флоп может сделать эту защелку не может, это выборки сигналов на краю clk. Сброс выдает значение выходного значения в постоянное значение. Это может быть реализовано защелкой, которая предпочтительнее с помощью инструментов синтеза из-за ее нижней области. Сигнал 'y' в вашем примере действует как флоп, потому что теперь' nrst' действует как сигнал синхронизации и отсчитывает входное значение на своем краю. Это невозможно сделать с помощью одной защелки. Обратите внимание, что хотя вы указываете @negedge rst, потому что вывод назначается константе, он не обязательно должен быть чувствительным к краю. Достаточно модуля, чувствительного к первому уровню. – Ari

+0

Когда константа находится в правой части задания, поведение защелки и триггера эквивалентно. Это не проблема. Вы упоминаете сигнал 'y', и это то, где вещи становятся странными, потому что как' y', так и 'z' синтезируются как защелки, и я утверждаю, что это не может быть правдой. Поскольку в правой части присваивания есть переменная (сигнал), функциональность последних двух блоков ('y' и' z') не может быть эквивалентной (см. Мой добавленный анализ и форму волны). – evilpascal