|
Эксперимент по CDC |
|
|
|
Dec 28 2012, 12:25
|
Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 3-09-12
Пользователь №: 73 371

|
Всем привет. Во всех статьях при перебросе с одного домена в другой шины данных пишут о том, что надо использовать асинхронное фифо или коды Грея. Мне стало интересно, через сколько воспроизведется "плохая" ситуация, если нарушить эти рекомендации. Для этого я набросал такой тест: Используя два клока 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) Или я что-то делаю не так?
Сообщение отредактировал johan - Dec 28 2012, 12:27
--------------------
|
|
|
|
|
 |
Ответов
|
Dec 28 2012, 14:51
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(johan @ Dec 28 2012, 16:25)  Всем привет. Во всех статьях при перебросе с одного домена в другой шины данных пишут о том, что надо использовать асинхронное фифо или коды Грея. Мне стало интересно, через сколько воспроизведется "плохая" ситуация, если нарушить эти рекомендации. Для этого я набросал такой тест: Используя два клока clk1 = 41.667 МГц и clk2 = 156.25 MГц. Счетчик тактируется частотой clk1, затем перебрасывается на clk2 и потом обратно. Смотрится разница между счетчиком и обратно переброшенным значением, и запоминается максимальное значение разницы. Вопросы: 1) Почему нет ошибок при неправильном переходе с одного домена на другой? 2) Или я что-то делаю не так?  Если опустить сбросы, то можно примерно так: Код logic [63:0] cnt, reg_other, reg_back, err_cnt, diff; logic err; always @(posedge clk2) begin cnt <= cnt+1'b1; reg_back <= reg_other; diff <= cnt - reg_back; err <= diff > 10; err_cnt <= err_cnt + err; end always @(posedge clk1) reg_other <= cnt; Это параллельный асинхронный перенос шины из одного клокового домена в другой и обратно. Ошибки должны пойти косяками даже без метастабильности за счёт разной длины роутинга. Что Вы написали, я вообще не врубился, честно говоря.
|
|
|
|
|
Dec 28 2012, 15:06
|
Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 3-09-12
Пользователь №: 73 371

|
Цитата(Timmy @ Dec 28 2012, 18:51)  Ошибки должны пойти косяками даже без метастабильности за счёт разной длины роутинга. Я знаю, что они должны были пойти, но за четыре часа на реальном железе ни одной ошибки не произошло, и это для меня не понятно. Поэтому я и создал этот топик, что бы спросить почему ошибки не происходят.
--------------------
|
|
|
|
|
Dec 28 2012, 16:40
|
Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 3-09-12
Пользователь №: 73 371

|
Цитата(bogaev_roman @ Dec 28 2012, 19:39)  Клоки должны плыть относительно друг друга по времени (и при этом примерно одинаковые). Вы указали две частоты - clk1 = 41.667 МГц и clk2 = 156.25 MГц. Каким образом они формируются и есть ли уверенность, что эти значения точные (может они формируются на одной pll и сапр автоматически их округляет до каких то значений без ухода фазы с соотношением скажем 2/7)? clk1 формируется из pll, где inclk 25 МГц от внешнего генератора частот. Multiply 5, divide 3. clk2 берется из внешнего генератора частот. Цитата(TRILLER @ Dec 28 2012, 19:36)  Здесь у вас реализован классический перенос данных из одного клокового домена в другой через 2 триггера. Из-за того, что у вас первая частота низкая, то значение счётчика легко подхватывается второй частотой, а потом передаётся обратно. Так вполне можно делать, если у вас одна частота эдак в 4 раза меньше второй. Из-за того, что фазы клоков плывут, рано либо поздно наступит момент, который я прикладываю в аттаче: счетчик cnt1 примет новое значение, и сразу же защелкнутся триггера сnt_156_sync_dl. Из-за разницы длины путей для разных бит может получиться так, что некоторые защелкнутся по новому значению, некоторые - не изменятся - останутся прежние.
Сообщение отредактировал johan - Dec 28 2012, 16:41
Эскизы прикрепленных изображений
--------------------
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|