module synchronizer(
input wire signal,
input wire clk,
output wire signal_sync
);
reg a,b;
always @(posedge clk)
begin
b<=a;
a<=signal;
end
assign signal_sync = b;
endmodule
После компиляции такого модуля средой Altera Quartus II в его RTL Viewer видна получившаяся эквивалентная схема:
Как раз это то, что нужно.
Асинхронный сигнал фиксируется по фронту clk в регистре a и существует вероятность, что после него сигнал будет некоторое время метастабильный. После фиксации в регистре b сигнал можно уже считать стабильным.
Часто синхронизатор не выделяют в отдельный модуль, а просто, где нужно, описывают его в тексте программы Verilog.
В виде сдвигового регистра:
reg [1:0]sync;
always @(posedge clk)
sync <= { sync[0], signal };
wire signal_sync;
assign signal_sync = sync[1];
Здесь в двухбитный регистр sync по фронту clk записывается 2х битное число: в старшем бите сигнал sync[0], а в младшем – signal. Это описание принципиально ни чем не отличается от первого, просто иная запись.
Синхронизатор нужно ставить там, где фиксируемый в D-триггере сигнал является асинхронным к тактовой частоте. Подробно о проблеме метастабильности триггера написано вот здесь.
Подробнее...