Синхронизатор сигнала для CDC на Verilog

В языке Verilog HDL для описания синхронизаторов сигналов, пересекающих клоковый домен (CDC, Clock Domain Cross) используются очень простые конструкции. Это понятно, ведь синхронизатор это просто два (редко три) последовательных триггера.
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 видна получившаяся эквивалентная схема:
Синхронизатор Clock Domain Cross

Как раз это то, что нужно.
Асинхронный сигнал фиксируется по фронту 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-триггере сигнал является асинхронным к тактовой частоте. Подробно о проблеме метастабильности триггера написано вот здесь.

 

 


Добавить комментарий