Может ли кто-нибудь объяснить мне, почему вместо триггера следует выводить защелку?
always_ff @ (posedge clk, negedge rst)
begin
if (!rst)
a <= '0;
end
Разве тот факт, что блок always чувствителен к фронту сигнала, не должен быть достаточным, чтобы сделать вывод о триггере. В этом случае, когда срабатывает отрицательный фронт сброса, он получает 0, иначе он сохраняет прежнее значение.
Этот вопрос исходит из выбранного лучшего ответа из этого вопроса о стеке:
System Verilog always_latch против always_ff
===========================================================================
Я поделюсь здесь тем, что узнал до сих пор. Причина, по которой это синтезируется в защелку, а не в триггер, заключается в том, что с правой стороны назначения находится КОНСТАНТА. В этом случае поведение защелки и триггера ЭКВИВАЛЕНТНО, потому что не имеет значения, захватывает ли он входное значение на фронте сигнала (триггер) или при включенной фиксации входа (защелка) так как ввод не меняется. Таким образом, инструмент синтеза выбирает элемент, который требует меньше ресурсов, то есть защелку.
С другой стороны, если бы в правой части присваивания была ПЕРЕМЕННАЯ, синтез должен был бы вывести триггер, потому что будет иметь значение, будет ли входной сигнал дискретизирован по краю (триггер) или во время включения фиксации входа (защелкивания), это означает, что два логических элемента НЕ ЭКВИВАЛЕНТНЫ.
Вот пример. Первые два блока всегда будут синтезироваться в защелку (в Quartus 14), что нормально, поскольку они эквивалентны из-за константы. Но блоки 3. и 4. always также будут синтезированы в защелку, что не является предполагаемым поведением, и эти блоки не эквивалентны! Блок 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. явно различаются, как видно на этой форме волны из приведенного выше моделирования:
Блок 3. (tb_y) ведет себя как асинхронный триггер, а блок 4. (tb_z) ведет себя как защелка. Но инструмент синтеза предполагает фиксацию в обоих случаях.
Если кто-то может пролить свет на это или прокомментировать код или форму волны, это будет очень полезно.