Dual edge flip flop
Недавно, понадобился триггер, работающий по обоим фронтам сигнала. Поиски в нете ни одного готового верилог-решения не обнаружили, так-что, выкладываю свою реализацию

Триггер состоит из двух триггеров, работающих по разным фронтам. Дабы не тянуть резину, вот реализация:
module DDR_FF(input set, reset, clk, in, output out);
reg ff_rise, ff_fall;
always@ (posedge set, posedge reset, posedge clk) begin
if (reset == 1)
ff_rise = 0;
else if (set == 1)
ff_rise = 1;
else if (clk == 1) begin
if (in == 1)
ff_rise = !ff_fall;
else
ff_rise = ff_fall;
end
end
always@ (posedge set, posedge reset, negedge clk) begin
if (reset == 1)
ff_fall = 0;
else if (set == 1)
ff_fall = 0;
else if (clk == 0) begin
if (in == 1)
ff_fall= !ff_rise;
else
ff_fall= ff_rise;
end
end
assign out = (set == 1) ? 1'b1 : (reset == 1) ? 1'b0 : ff_rise ^ ff_fall;
endmodule
set – асинхронная установка, reset – асинхронный сброс, оба с прямыми логическими уровнями. Остальное – думаю, понятно.
Проверка асинхронных входов в последнем assign’е сделана, чтобы избежать глитчей.
Вдохновением служила вот эта статья:
О, пасиба 🙂 Думаю фпгашникам тема будет актуальна — в нете практически нет толковых подсказок за редким исключеним…
В своё время рашал эту задачу, с кучей костылей…
Во втором олвейсе асинхронная установка походу неработает.
Как это, не работает?
ff_fall = 0;
а. ну да)
Мож объяснить как последняя строчка работает?
Ну, давай на словах напишу тоже-самое.
Если set=1, то на выходе 1
Если reset=1, то на выходе 0
Если оба предыдущих условия не верны, на выходе — ff_rise ^ ff_fall
Спасибо. впринципе догадывался но всеравно не могу понять как работает эта конструкция?
Кажется забыли указать самое важно слово «ИНАЧЕ». Получается конструкция типа switch:
Если set=1, то на выходе 1
Иначе если reset=1, то на выходе 0
Иначе на выходе ff_rise ^ ff_fall