|
|
  |
Эксперимент по 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, 15:36
|
Частый гость
 
Группа: Свой
Сообщений: 180
Регистрация: 17-02-09
Из: Санкт-Петербург
Пользователь №: 45 001

|
"Во всех статьях при перебросе с одного домена в другой шины данных пишут о том, что надо использовать асинхронное фифо или коды Грея." Вы ошибаетесь - рекомендуется использовать асинхронное фифо в котором клоковый переход между адресами чтения и записи осуществляется счётчиками, реализованными на коде Грея. Код Грея как бы удерживает каждый бит счётчика 2(и более) периода той частоты, которая его формирует. Таким образом появляется в 2 раза больше времени на подхват этого значеня другим клоком. Без него на близких частотах всё сломается. Можете попробовать на вашем примере, только вместо 42 МГц задайте, к примеру, 120МГц. CODE 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
Здесь у вас реализован классический перенос данных из одного клокового домена в другой через 2 триггера. Из-за того, что у вас первая частота низкая, то значение счётчика легко подхватывается второй частотой, а потом передаётся обратно. Так вполне можно делать, если у вас одна частота эдак в 4 раза меньше второй.
Сообщение отредактировал TRILLER - Dec 28 2012, 15:46
|
|
|
|
|
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
Эскизы прикрепленных изображений
--------------------
|
|
|
|
|
Dec 28 2012, 17:14
|
Частый гость
 
Группа: Свой
Сообщений: 128
Регистрация: 19-08-10
Из: Смоленск
Пользователь №: 58 991

|
Может все дело в том, что частоты которые Вы подаете хоть и из разных источников но фиксированы по фазе во времени, поэтому не случается тяжелого случая, когда фронты совпадают настолько, чтобы вызвать сбой по данным. Попробуйте сделать нечто такое, чтобы фронт одноги из генераторов "плавал туда, сюда" по фазе, так чтобы он с гарантией налетел на фронт второго генератора в течение нескольких секунд. При такой постановке Вы гарантированно получите сбой данных.
--------------------
Herz укроп и педрила
|
|
|
|
|
Dec 28 2012, 19:51
|
Частый гость
 
Группа: Свой
Сообщений: 78
Регистрация: 3-09-12
Пользователь №: 73 371

|
Цитата(dvladim @ Dec 28 2012, 22:42)  Внешние генераторы для clk1 и clk2 разные? Если нет - эксперимент некорректен. Разные) Пока есть идея, что для этого эксперимента неправильно использовать счетчик - не так много бит меняется и вероятность возникновения ошибки мала. Возможно лучше попробовать сдвиговый регистр, что бы все биты менялись каждый такт в cnt1.
Сообщение отредактировал johan - Dec 28 2012, 19:53
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|