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

 
 
 
Reply to this topicStart new topic
> Эксперимент по 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
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
Копейкин
сообщение Dec 28 2012, 15:20
Сообщение #4


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

Группа: Участник
Сообщений: 190
Регистрация: 7-11-07
Из: С-Петербург
Пользователь №: 32 134



Эксперимент некорректный.
Переключение тактовой частоты - случай не самый тяжелый.
Плохо, когда изменение сигнала происходит на активном перепаде тактовой частоты, см. метастабильность.
Плохо, когда длительность передаваемого импульса короче периода тактовой частоты.
И т.п.
Go to the top of the page
 
+Quote Post
TRILLER
сообщение Dec 28 2012, 15:36
Сообщение #5


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

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение Dec 28 2012, 15:39
Сообщение #6


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

Группа: Свой
Сообщений: 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
Сообщение #7


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

Группа: Свой
Сообщений: 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
novchok
сообщение Dec 28 2012, 17:14
Сообщение #8


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

Группа: Свой
Сообщений: 128
Регистрация: 19-08-10
Из: Смоленск
Пользователь №: 58 991



Может все дело в том, что частоты которые Вы подаете хоть и из разных источников но фиксированы по фазе во времени, поэтому не случается тяжелого случая, когда фронты совпадают настолько, чтобы вызвать сбой по данным. Попробуйте сделать нечто такое, чтобы фронт одноги из генераторов "плавал туда, сюда" по фазе, так чтобы он с гарантией налетел на фронт второго генератора в течение нескольких секунд. При такой постановке Вы гарантированно получите сбой данных.


--------------------
Herz укроп и педрила
Go to the top of the page
 
+Quote Post
dvladim
сообщение Dec 28 2012, 18:42
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 654
Регистрация: 24-01-07
Из: Воронеж
Пользователь №: 24 737



Цитата(johan @ Dec 28 2012, 20:40) *
clk1 формируется из pll, где inclk 25 МГц от внешнего генератора частот. Multiply 5, divide 3.
clk2 берется из внешнего генератора частот.

Внешние генераторы для clk1 и clk2 разные? Если нет - эксперимент некорректен.
Go to the top of the page
 
+Quote Post
johan
сообщение Dec 28 2012, 19:51
Сообщение #10


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

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



Цитата(dvladim @ Dec 28 2012, 22:42) *
Внешние генераторы для clk1 и clk2 разные? Если нет - эксперимент некорректен.


Разные)

Пока есть идея, что для этого эксперимента неправильно использовать счетчик - не так много бит меняется и вероятность возникновения ошибки мала. Возможно лучше попробовать сдвиговый регистр, что бы все биты менялись каждый такт в cnt1.

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


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

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

 


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


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