реклама на сайте
подробности

 
 
> Эксперимент по CDC
johan
сообщение Dec 28 2012, 12:25
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 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) Или я что-то делаю не так? sm.gif

Сообщение отредактировал johan - Dec 28 2012, 12:27


--------------------
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Timmy
сообщение Dec 28 2012, 14:51
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(johan @ Dec 28 2012, 16:25) *
Всем привет.
Во всех статьях при перебросе с одного домена в другой шины данных пишут о том, что надо использовать асинхронное фифо или коды Грея. Мне стало интересно, через сколько воспроизведется "плохая" ситуация, если нарушить эти рекомендации.

Для этого я набросал такой тест:
Используя два клока clk1 = 41.667 МГц и clk2 = 156.25 MГц. Счетчик тактируется частотой clk1, затем перебрасывается на clk2 и потом обратно. Смотрится разница между счетчиком и обратно переброшенным значением, и запоминается максимальное значение разницы.
Вопросы:
1) Почему нет ошибок при неправильном переходе с одного домена на другой?
2) Или я что-то делаю не так? sm.gif

Если опустить сбросы, то можно примерно так:
Код
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;

Это параллельный асинхронный перенос шины из одного клокового домена в другой и обратно. Ошибки должны пойти косяками даже без метастабильности за счёт разной длины роутинга.
Что Вы написали, я вообще не врубился, честно говоря.
Go to the top of the page
 
+Quote Post
johan
сообщение Dec 28 2012, 15:06
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 78
Регистрация: 3-09-12
Пользователь №: 73 371



Цитата(Timmy @ Dec 28 2012, 18:51) *
Ошибки должны пойти косяками даже без метастабильности за счёт разной длины роутинга.


Я знаю, что они должны были пойти, но за четыре часа на реальном железе ни одной ошибки не произошло, и это для меня не понятно. Поэтому я и создал этот топик, что бы спросить почему ошибки не происходят.


--------------------
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Dec 28 2012, 15:39
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 088
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



Цитата(johan @ Dec 28 2012, 19:06) *
Я знаю, что они должны были пойти, но за четыре часа на реальном железе ни одной ошибки не произошло, и это для меня не понятно. Поэтому я и создал этот топик, что бы спросить почему ошибки не происходят.

Клоки должны плыть относительно друг друга по времени (и при этом примерно одинаковые). Вы указали две частоты - clk1 = 41.667 МГц и clk2 = 156.25 MГц. Каким образом они формируются и есть ли уверенность, что эти значения точные (может они формируются на одной pll и сапр автоматически их округляет до каких то значений без ухода фазы с соотношением скажем 2/7)?
Какой-то алгоритм непонятный, кстати. Я бы формировал значения счетчика на частоте 1, записывал в регистр на частоте 2 (возможно с делителями) и при этом локально запускал точно такой же счетчик на частоте 2 и сравнивал значения опять же на частоте 2.
Go to the top of the page
 
+Quote Post
johan
сообщение Dec 28 2012, 16:40
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 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
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 04:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01423 секунд с 7
ELECTRONIX ©2004-2016