Вот простая задача: выделение момента изменения длительного сигнала.
Я выделил ее в отдельную статью, потому, что это весьма часто используемый технический прием. Такие вещи приходится писать довольно часто и уже почти не задумываешься над ними.
Идея в общем очень простая. Есть длительный сигнал signal. С некоторой частотой clk запоминаем его значение в регистре prev_signal. Потом сравниваем текущее значение сигнала signal и его предыдущее значение prev_signal. На основании этого "сравнения" выдаем результат.
Выделяем момент фронта.
Фрагмент кода на языке Verilog выглядит вот так:
reg prev_signal;
always @(posedge clk)
prev_signal <= signal;
wire front_edge;
assign front_edge = ~prev_signal & signal;
Вот что получается при синтезе этого кода (смотрю программой Altera Quartus II RTLViewer):
Временная диаграмма поясняет принцип работы:
Теперь определяем момент спада сигнала.
Код на Verilog примерно такой же:
reg prev_signal;
always @(posedge clk)
prev_signal <= signal;
wire back_edge;
assign back_edge = prev_signal & ~signal;
Из этого кода получается вот такая логика:
Ну и вот "времянка":
Выделяем моменты и фронта и спада.
Точно так же мы можем найти и все моменты изменения сигнала:
reg prev_signal;
always @(posedge clk)
prev_signal <= signal;
wire both_edges;
assign both_edges = prev_signal ^ signal;
Соответствующая схема:
И ее временная диаграмма:
Вроде бы все просто? Да так и есть! Но еще раз повторюсь - эти "шаблоны" кода используются в разных проектах довольно часто.
Подробнее...