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