Перейти к содержанию
    

Xilinx 10G ethernet + AXI DMA

Добрый день. У меня, что называется, быстровопрос, для тех кто в теме.

Никогда ранее не работал с ethernet и вообще пакетной передачей. Использую 10G/25G Ethernet subsystem и к нему прикручен AXI DMA контроллер (примерно как в https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842542/Baremetal+XXV+Ethernet+driver   с тем отличием что у них MCDMA, у меня просто DMA), который берет данные для передачи из памяти и пихает в stream-интерфейс ethernet. И точно так же берет принимаемые данные из stream-интерфейса и пишет в память. Никакого fifo-буфера между ними нет. Данные пока передаю в простом loopback на трансивере самому себе.

При передаче пакетов я вижу, что в процессе подачи данных на ethernet-контроллер на потоковом интерфейсе могут возникать паузы когда tvalid уходит в 0. Контроллер воспринимает это, видимо, как окончание пакета (несмотря на отсутствие tlast). В итоге на приемной стороне я вместо одного пакета вижу пачку невалидных пакетов разной длины (и, видимо, не в loopback-тесте, а через настоящий свитч, эти пакеты не пройдут). По моим представлениям это должно работать как-то не так.

Я так понимаю, нужно обеспечить непрерывную подачу данных на ядро ethernet:

  1. Увеличить скорость памяти. Но не факт, что это решит проблему (а с внешней DDR точно не решит)
  2. Поставить FIFO-буфер размером в один пакет. Но это какой-то перерасход ресурса (особенно если использовать jumbo-фреймы) и лишняя задержка - нужно включить fifo в packet mode чтобы он накапливал весь пакет, потом только отдавал дальше.

Что вообще обычно с этим делают?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

21 minutes ago, alexadmin said:

Что вообще обычно с этим делают?

Читают доки для начала  :biggrin:  
Сеть не может ждать когда данные будут доступны  - поэтому если начали передачу пакета то tvalid должен быть непрерывен
Обеспечить это для данных из DDR памяти кроме как буферным FIFO не получится. Размер FIFO должен покрывать макс. задержки которые могут быть при чтении из памяти. Ну или как вы заметили при пакетом режиме FIFO на макс размер пакета.  
 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, RobFPGA said:

Сеть не может ждать когда данные будут доступны  - поэтому если начали передачу пакета то tvalid должен быть непрерывен

tvalid то может и быть непрерывным, но передавая данные, нужно также анализировать tready. Точно не скажу за 10G, но в Aurora tready стабильно периодически падает в ноль. Поэтому передать пакет непрерывно в AXI Stream не получится, он может разрываться паузами. tlast - это как раз и есть признак окончания пакета. Более того, есть ещё tkeep, который анализируется только при tlast = 1. Поэтому если контроллер не анализирует tlast, что-то не так  с контроллером.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

1 minute ago, attaboy said:

tvalid то может и быть непрерывным, но передавая данные, нужно также анализировать tready.

Естественно что передавать  данные  нужно по комбинации tvalid && tready. Только вот для 10G  есть условие что выставив tvalid в начале пакета вы не можете его снимать до окончания (с подтверждением tlast). Если же сняли то это считается как underflow событие и в сеть уйдет испорченный пакет. 

Давно уже с Aurora не работал но помнится мне что в отличие от 10G  там вроде есть возможность вставки/удаления в поток данных выравнивающих символов  что позволяет компенсировать разницу в тактовых на передающем и приемном конце. Отсюда может быть периодичность снятия tready (в момент вставки таких символов) при передаче. 
В 10G этого нет - тут  полностью синхронный поток данных. Поэтому tready может сниматься только в начале пакета  когда передается синхронизация.   Но конкретно это зависит от логики реализованной в корке и надо опять же смотреть доки. 

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 minutes ago, RobFPGA said:

В 10G этого нет - тут  полностью синхронный поток данных.

Странно. Неужели в 10G нет каких-нибудь K-символов, которые периодически вставляются в поток для подстройки rx_clk? Как вы правильно заметили, именно из-за этих символов  происходит периодеское падение tready.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, в общем я все правильно придумал. Просто ввело в некоторое недоумение что у зайлинкса в их примере про фифо ничего нет...

PS Буфер непосредственно внутри ядра есть на приемной стороне, он и выравнивает скорости. Если буфер не использовать, то они предлагают тактировать интерфейс данных восстановленным клоком.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

2 hours ago, attaboy said:

Странно. Неужели в 10G нет каких-нибудь K-символов, которые периодически вставляются в поток для подстройки rx_clk?

Aurora изначально это потоковый линк. Соответвенно вы можете гнать фреймы данных разного, неограниченного сверху размера. Поэтому для компенсации тактовых и нужно периодически вводить выравнивающие символы в поток. Что естественно уменьшает пиковую скорость передачи. 
В 10G  пакетная передача с фикс. макс. размером. Поэтому наверное и решили что компенсация тактовых в данных не нужна (для сохранения макс. скорости), а для компенсации будет достаточно межпакетных интервалов. Поэтому в данных пакета 10G нет выравнивающих символов.  А жаль, будь такая возможность в 10G некоторые вещи можно было бы делать проще.  :yes3: 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 часов назад, RobFPGA сказал:

В 10G  пакетная передача с фикс. макс. размером. Поэтому наверное и решили что компенсация тактовых в данных не нужна (для сохранения макс. скорости), а для компенсации будет достаточно межпакетных интервалов. Поэтому в данных пакета 10G нет выравнивающих символов.  А жаль, будь такая возможность в 10G некоторые вещи можно было бы делать проще.  :yes3: 

Там есть нюанс. Если гнать, например, пакеты непрерывно, без пауз (не считая IPG - interpacket gap), разница в тактовых линк-партнёров может приводить к тем же самым эффектам. И там есть в протоколе средство решения этой проблемы - при накоплении приёмного буфера, приёмная сторона может слать специальные служебные пакеты передающей, чтобы та иногда (как раз по этому требованию) делала IPG чуть длиннее, чем требует спека (12 символов). У нас парни на это налетели, не могли приличное время понять, почему входные буфера приёмника иногда переполняются, искали ошибку в логике. Решилось задействованием этой части протокола. Но сам пакет, да, летит без пауз, иначе быть не может. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

2 minutes ago, dxp said:

И там есть в протоколе средство решения этой проблемы - при накоплении приёмного буфера, приёмная сторона может слать специальные служебные пакеты передающей, чтобы та иногда (как раз по этому требованию) делала IPG чуть длиннее, чем требует спека (12 символов).

Это все же немного другое чем выравнивание тактовых.  Это чистый flow-control.  Причем этот flow-control может быть как общий на линк, так и раздельный для разных типов траффика.    
Я сам таким пользовался когда гнал UDP траффик из FPGA параллельно через несколько 10G линков.   

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, конечно, по общей схеме это flow control (специальные протокольные пакеты участвуют). Вспомнилось просто, что там тоже по итогу присутствует вставка пауз. Кстати, тут ещё важное отличие в том, что подстройка только в одну сторону - если приёмник медленнее. Если наоборот, то ничего делать не надо. При выравнивании тактовых на низком уровне там в обе стороны подстройка делается (elastic buffer контролируется как на overflow так и на underflow). Что интересно, вроде тот же PCIe пакетный протокол (TLP, DLLP), однако физическая сигнализация там как для потоков (c elastic буферами, IDLE, SKIP паттернами (ordered set'ами) и т.д.).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, dxp said:

Вспомнилось просто, что там тоже по итогу присутствует вставка пауз.

Сердце трансивера - блок CDR (Clock Data Recovery), в терминологии Xilinx. Этот блок из входного потока извлекает как данные, так и тактовый сигнал. Для корректного извлечения данных необходим такой же тактовый сигнал, как и у удаленного передатчика, иначе неизбежно будут появляться ошибки. В трансивере есть так называемый сигнал rxout_clk. Это именно тот клок, на котором CDR декодирует данные. При включении питания rxout_clk = refclk. При таком равенстве CDR работать не будет. Поэтому затем начинается процесс подстройки rxout_clk под частоту удаленного передатчика. Она почти равна refclk (допустим 156,25 МГц), но всегда отличается на какие-то ppm'ы. Если CDR подстроился под эту частоту, залочился, декодирование данных происходит нормально. Если нет - на входе появляются некорректные данные. И для того, чтобы сохранить эту синхронизацию, в потоке входных данных должны быть спецсимволы, из которых легче извлечь тактовый сигнал. Что-то типа 010101010. Эти спецсимволы - не паузы. Это необходимый элемент любого высокоскоростного последовательного интерфейса.

 

 

16 hours ago, RobFPGA said:

В 10G  пакетная передача с фикс. макс. размером. Поэтому наверное и решили что компенсация тактовых в данных не нужна (для сохранения макс. скорости), а для компенсации будет достаточно межпакетных интервалов.

Да уж, похоже каждый ваяет свой протокол в соответствии со своими представлениями. Например SATA - это тоже протокол с пакетной передачей с фикс. макс. размером. Но там максимум через 254 32-х битных слова рекомендуется/необходимо вставлять как минимум два примитива ALIGN. Предположу, что в SATA размер пакета больше - до 2048 32-х битных слова. Но ведь в Ethernet'е есть Jumbo frames, которые даже несколько крупнее, чем в SATA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 минут назад, attaboy сказал:

Эти спецсимволы - не паузы.

rEy6x5N.png

 

https://en.wikipedia.org/wiki/Ethernet_flow_control, Pause Frame

 

Приём на входе (CDR) всегда осуществляется на захваченной из входного потока частоте (PLL приёмника под неё подстраивается). Дальше данные поступают на схему CDC (чаще всего elastic buffer), с выхода которой забирают данные уже на "местной" частоте. Чтобы буфер не переполнялся, в поток либо втыкаются SKIP паттерны (PCIe, например), либо буфер имеет размер, достаточный для приёма пакета максимальной длины, а общая скорость регулируется - см. выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...