Во всех статьях при перебросе с одного домена в другой шины данных пишут о том, что надо использовать асинхронное фифо или коды Грея. Мне стало интересно, через сколько воспроизведется "плохая" ситуация, если нарушить эти рекомендации.
Для этого я набросал такой тест:
Используя два клока clk1 = 41.667 МГц и clk2 = 156.25 MГц. Счетчик тактируется частотой clk1, затем перебрасывается на clk2 и потом обратно. Смотрится разница между счетчиком и обратно переброшенным значением, и запоминается максимальное значение разницы.
Код:
CODE
logic cnt_rst;
logic cnt_rst2;
logic [63:0] cnt_41;
logic [63:0] cnt_156;
logic [63:0] cnt_41_back;
logic [63:0] cnt_156_sync_d1;
logic [63:0] cnt_41_back_sync_d1;
//главный счетчик
always_ff @( posedge clk_41m667 )
begin
if( cnt_rst )
cnt_41 <= '0;
else
cnt_41 <= cnt_41 + 1'd1;
end
always_ff @( posedge clk_156m25 )
begin
if( cnt_rst2 )
cnt_156_sync_d1 <= '0;
else
cnt_156_sync_d1 <= cnt_41;
end
always_ff @( posedge clk_156m25 )
begin
if( cnt_rst2 )
cnt_156 <= '0;
else
cnt_156 <= cnt_156_sync_d1;
end
//перебрасываем обратно на 41.667
always_ff @( posedge clk_41m667 )
begin
if( cnt_rst )
cnt_41_back_sync_d1 <= '0;
else
cnt_41_back_sync_d1 <= cnt_156;
end
always_ff @( posedge clk_41m667 )
begin
if( cnt_rst )
cnt_41_back <= '0;
else
cnt_41_back <= cnt_41_back_sync_d1;
end
logic [63:0] diff;
logic [63:0] max_diff;
logic [63:0] cnt_41_save;
logic [63:0] cnt_41_back_save;
logic [63:0] diff_buf;
always_comb
begin
if(cnt_41_back > cnt_41)
diff = cnt_41_back - cnt_41;
else
diff = cnt_41 - cnt_41_back;
end
always_ff @( posedge clk_41m667 )
begin
if( cnt_rst )
begin
max_diff <= '0;
cnt_41_save <= '0;
cnt_41_back_save <= '0;
end
else
if( ( diff >= max_diff ) && ( cnt_41_back > 10 ) )
begin
max_diff <= diff;
cnt_41_save <= cnt_41;
cnt_41_back_save <= cnt_41_back;
end
end
Сбросы управляются с mcu, поэтому в коде этого нету. Клоки выбрал так, что бы количество соотношений фаз между клоками было как можно больше: поэтому выбрал два клока у который НОК большой. Период соотношения фаз равен 156250 тактов clk1.
Результаты эксперимента на реальном железе (Altera Cyclone IV): за 4 часа на зафиксировано ни одной ошибки: максимальная разница между счетчиками была равна 2 (двум).
Вопросы:
1) Почему нет ошибок при неправильном переходе с одного домена на другой?
2) Или я что-то делаю не так?
