Обновить
16
0
Игорь Фомин@neerps

Разработчик систем на базе FPGA и МК

Отправить сообщение
Спорная ситуация. Я не читал полностью спецификацию PCI-Express, но у меня сложилось мнение, что пока устройство не получит подтверждение на какой-то пакет, оно будет слать его вечно.

Похоже, что в первые несколько раз, когда я читал спецификацию, эту часть я упустил. В памяти хорошо отложился REPLAY_TIMER — счетчик времени, по которому передатчик решает, что пора повторно отправлять пакет. Но вот что происходит, когда приемник несколько раз отправляет обратно NACK, я не осознал. Выходит, что существует счетчик повторов REPLAY_NUM. Если счетчик повторов превышен, тогда канальный уровень просит физический уровень повторить инициализацию канала (подразумеваю retraining).
Выходит, что здесь Вы правы, и ядро будет отправлять пакет вечно. Теперь мне стала более понятна ситуация, в которой ПК вис, когда я формировал ответы на чтение с ошибочным адресом.

И отслеживая выводы Flow Control, чего Вы добьетесь? Зная, что на DLL уровне осталось место под пару пакетов, прекратите формирование пакетов на TLP уровне? Так для этих целей и есть флаг tx_ready.

Если, к примеру, у меня есть исходящий ответ на чтение, то я отправлю его, пока счетчики кредитов для запросов записи обновляются через DLLP.
Я столкнулся с тем, что хотя флаг «tx_st_ready» был в единице, счетчик кредитов был меньше, чем размер пакета, который я отправлял ядру. В результате ядро роняло флаг «tx_st_ready» в ноль и держало его так 100 тактов и даже дольше. Пока я не отладил проверку Flow Control, проблема не ушла. Конечно, я не исключаю, что это в принципе была проблема моей логики как таковой, и другой разработчик не столкнется с моей ситуацией в принципе.

Тем не менее, подраздел «Link Hangs in L0 State» внутри раздела «Debugging» описывает случай переполнения счетчика кредитов. Цитата для Cyclone V:
Determine if the credit field associated with the current TLP type in the tx_cred bus is less than the requested credit value. When insufficient credits are available, the core waits for the link partner to release the correct credit type. Sufficient credits may be unavailable if the link partner increments credits more than expected, creating a situation where the Cyclone V Hard IP for PCI Express IP Core credit calculation is out-of-sync with the link partner.

Я могу трактовать это только так, что за выходами Flow Control всё же стоит следить.
Во-первых, длина запросов ограничена одним двойным словом (DWORD).
Это не так. Спецификация (данные из спецификации на ревизию 3.0) указывает, что количество DW в TLP может быть от 1 до 1024. Драйвер AHCI от Microsoft для Windows 7 (версию драйвера не помню за давностью лет) умеет посылать в PIO режиме запросы размером в 2 DW.

Здесь я действительно сформулировал текст с ошибкой, неточно. Когда писал материал, то думал про BAR с шириной в 32 бита, так как сам использовал только такой вариант. В случае с BAR в 64 бита, длина запроса точно не может быть меньше 2 DW. Это нужно будет обязательно уточнить, спасибо!
Другая ситуация возникает, если мы формируем запрос с адресом, который не был выровнен по DWORD. В этом случае размер запроса становится больше: 2 DW для BAR 32 бита и 3 DW для BAR 64 бита. Но при этом в запросе поля byte enable выставлены так, что фактически внутри 2 DW или 3 DW полезные байты занимают меньше. Т.е. при смещенном адресе мы всё равно получаем не больше 1 DW для BAR 32 бита и не больше 2 DW для BAR 64 бита. Всё остальное оказывается мусором. По крайней мере, в моих экспериментах было так.

Первая группа особенностей связана со способами, которые позволяют сконфигурировать ПЛИС в течение 100 мс по требованиям PCIe.
Отсчет времени ведется от того момента, когда все напряжения питания выйдут на стабильный уровень. При работе с большими ПЛИС достаточно жесткий критерий.

Здесь я хотел обратить внимание именно на способы, которые помогают ПЛИС сконфигурироваться и вовремя активировать ядро, так как именно эта часть вызывала у меня наибольшие трудности. До PCIe я спокойно обходился простейшим Active Serial, где всё за меня делало готовое IP от производителя. Здесь же пришлось поломать голову над Fast Passive Parallel, посмотреть на Configuration over Protocol. В противном случае большие ПЛИС действительно не успевают прогрузиться. Но, наверное, всё равно стоит уточнить то, с какого события отсчитывать 100 мс. Учту.

Напоследок, разработчикам настоятельно рекомендуется использовать информацию о доступных кредитах для исходящих пакетов
Из ядра есть выводы с DLL, которые показывают наличие свободных буферов у устройства-партнера (Flow Control)?

Выводы для Flow Control есть. По умолчанию они показывают текущий лимит. Дело именно в том, что в самой документации на ядро сказано: «The Application Layer may track credits consumed and use the credit limit information to calculate the number of credits available». В дополнение к этому, примеры проектов с сайта производителя, которые я нашел, не использовали выводы в принципе. Да, в документации также сказано, что «Hard IP also checks the available credits before sending a request to the link, and if the Application Layer violates the available credits for a TLP it transmits, the Hard IP blocks that TLP and all future TLPs until credits become available». То есть, с одной стороны всё выглядит так, будто бы разработчик вообще может не беспокоиться о кредитах, и ядро само разберётся. С другой стороны, возникает ситуация, когда какой-то пакет забивает передающий канал. Ядро опустит флаг «tx_ready», и никакие другие пакеты пройти не смогут. Моя позиция в том, чтобы отслеживать выходы Flow Control и не допускать подобных заторов.

Upd: Забыл назвать еще одну причину, по которой выводы Flow Control стоит отслеживать. В разделе «Debugging» в документации есть такой подраздел как «Link Hangs in L0 State». В этой ситуации ядро опускает флаг «tx_ready» и не выходит из этого состояния, пока его не сбросят. Одна из возможных причин — «Flow control credit overflows».
Описаниями ядра, конечно же, пользовался. Получилось, как с очками на носу: очевидные документы, которые достаточно долго время были рядом, добавить позабыл.
Спасибо, что отметили!
Большое спасибо за подробный обзор!

В своё время узнал про Йиржи Гейзлера благодаря одному комментарию с заброшенной ветки формуа Altera. Там говорили про некий необычный стиль описания логики на VHDL по методу Jiri Gaisler. В сети, в целом, оказалось не так и много информации про этот стиль. В одной из презентаций говорится о том, что именно благодаря этому стилю на LEON потратили 2 человеко-года (2 man-years), а первый образец в железе вышел без багов. Выглядит впечатляюще. Однако я практически не встречал разработчиков, которые писали бы подобным образом. И это меня несколько удивляет. Как я понял, LEON'ы оказались весьма успешными. В то же время, один из методов разработки этого успешного продукта не получил распространения. Для себя я пока не нашел ответа, почему.

Да, действительно, конкретный стандарт я не указал. Исправлю.


В целом, получается так, что physical layer, data link layer и даже часть transcation layer предоставляются как есть, от изготовителя ПЛИС. Они берут на себя отладку того, что предоставляют. На стороне разработчика остаётся только дополнить это логикой под конкретное приложение. Все потенциальные проблемы будут именно здесь.

До того, чтобы задействовать CvP у меня, к сожалению, руки пока не дошли. На что еще стоит обратить внимание, кроме версии Quartus?
Статья стала попыткой совместить ту информацию, что я встретил в разных источниках, и полного, добуквенного эквивалента, как мне показалось, у неё нет. Конечно, сейчас всё достаточно быстро меняется, и я мог что-то пропустить.

Я не стану отрицать, что в немалой степени опирался на формат материалов от Eli Billauer, например, в части примеров пакетов. В списке использованных источников есть ссылка на его статью. В своё время он проделал неплохую работу. Однако когда я впервые разбирался, а как вообще передавать данные, только лишь этих материалов мне не хватило. К примеру, Eli толком не рассматривает, как быть, если векторов прерываний несколько; не рассматривает случаи с большими потками данных, где прерывания могут съесть приличную порцию процессорного времени. На мой взгляд, общую картину того, что должно быть сделано, какой алгоритм обмена с драйвером в целом, намного лучше обрисовывают здесь и здесь. Но, опять же, это лишь кусочки всей мозаики, которые дополняют друг друга. Источника, в котором было бы собрано всё и сразу, я пока не видел.

Верификацию в статье я не затрагивал. Часть вопросов по соответствию решает канальный уровень ядра внутри ПЛИС. Тем не менее, для проверки своей логики без BFM не обойтись. Когда я писал контроллер, мне не удалось найти BFM от Altera под мою версию Quartus. Из условно-бесплатных нашел такой вариант. Какие-то косяки логики всё равно пришлось долавливать через экспорт воздействий из SignalTap в файл для тестбенча.

По тем вакансиям, что видел я, у меня сложилось впечатление, что на том же Java, например, стартовать проще. Зарплаты тех, кто пишет под ПЛИС, выглядят в большинстве ниже. Правда, смотрел я предложения российского рынка труда. Может, в международной выборке ситуация иная. Также мне показалось, что в случае IP под специализированные микросхемы (ASIC), ситуация лучше. Правда и хлопот там побольше, чем в случае с ПЛИС.

Можно ли называть языки аппаратного описания языками программирования? На мой взгляд, их стоит отделить.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность