2016-06-28 14 views
1

Для импульсов мы используем импульсный синхронизатор и для сигнала уровня, мы используем 2-флоп-синхронизатор, но что, если сигнал может быть импульсного или уровня. Есть ли способ синхронизировать это?Переключение тактовых импульсов для импульсного и уровня сигнала

ответ

0

Да, вы можете, но решение должно основываться на ширине входного импульса относительно выходных часов.

Когда выходные часы очень медленные, и у вас есть импульс, вам нужно добавить встроенный импульсный носитель, который работает во входном тактовом домене. Удлинение определяется шириной бита stretch_out ниже и «MUST» должно быть больше одного такта в выходном домене clk.

reg [3:0] stretch_out; 
always @ (posedge inclk) 
begin 
    stretch_out <= in_signal ? 4'b1111 : {stretch_out[2:0],1'b0}; 
end 

Теперь вы можете просто использовать синхронизатор с двойным флопом.

reg [1:0] out_sync; 
always @ (posedge outclk) 
begin 
    out_sync <= {out_sync[0],stretch_out[3]}; 
end 

Это должно синхронизировать уровень и импульс от быстрого домена в медленный домен.

Единственная проблема, заключается в том, что вы будете добавлять больше, чем просто обычную задержку с двумя флопами.

0

Вы можете асинхронно настроить с использованием сигнала в целевом домене, синхронизировать с помощью двойных флопов, а затем обнаружить нарастающий фронт. Должен работать как для коротких импульсов, так и для длинных уровней.

// Prevent DRC violations if using scan 
wire in_signal_n = scan_mode ? 1'b1 : !signal_in; 

// Following code creates a flop with both async setb and resetb 
reg sig_n_async; 
always @ (posedge outclk or negedge reset_n or negedge in_signal_n) 
    if (!reset_n) 
    sig_n_async <= 0; 
    else if (!in_signal_n) 
    sig_n_async <= 1; 
    else 
    sig_n_async <= 0; 


// Synchronizer 
reg [1:0] out_sync; 
always @ (posedge outclk or negedge reset_n) 
    if (!reset_n) 
    out_sync <= 0; 
    else 
    out_sync <= {out_sync[0],sig_n_async}; 


// Rising edge 
reg out_sync_del; 
always @ (posedge outclk or negedge reset_n) 
    if (!reset_n) 
    out_sync_del <= 0; 
    else 
    out_sync_del <= out_sync[1]; 

wire signal_out = out_sync[1] & !out_sync_del;