Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: PCIe and FPGA
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
polyvyannyy
Всем привет, уважаемые форумчане!
Возникла необходимость поднять на девборде PCIe 3x8. Референсный дизайн загружен и все работает.
Но теперь нужно сделать прием и отправку своих данных с/на хост. И вот тут то возникла куча вопросов и непониманий. Информации по теории PCIe полно, но никак не удается найти конкретики относительно ПЛИС...какой именно у меня должен быть порядок действий со стороны ПЛИС, чтобы организовать чтение/запись данных в ОЗУ хоста? таблица дискрипторов...кто её формирует, где она хранится?В голове каша и нет четкого понимания.
Прошу помощи у опытных в данной теме людей.
За любые ссылки, проекты, которые можно взять за основу, буду благодарен.
dsmv
Можно посмотреть на мой старый проект
http://ds-dev.ru/projects/ds-dma
AVR
Готов проконсультировать по всем вопросам касательно PCI-E. Насколько хватит моей скудной компетенции.
Только просьба, переименовать тему в сторону более информативного заголовка.

Вкратце: хост выделяет у себя кусочки памяти, затем делает их доступными для записи через PCI-E, попутно выясняя по какому адресу это будет видно через PCI-E. Эти адреса могут не совпадать. Все эти действия делаются API ядра операционной системы. Полученные адреса, например, можно засунуть через MMIO (т.е. BARы) в ПЛИС, а потом ПЛИС просто шлет пакеты, заполняя эти кусочки памяти. Можно для начала выделить 1 блок размером 4096.

На самом деле всё чудовищно просто, когда осваивал не мог понять/поверить что всё так просто.

http://xillybus.com/tutorials/pci-express-...utorial-guide-1
polyvyannyy
Цитата(dsmv @ Jun 5 2018, 22:09) *
Можно посмотреть на мой старый проект
http://ds-dev.ru/projects/ds-dma


Спасибо за ссылку!Буду изучать.
AVR
Продублирую из лички сюда, чтобы осталось. Всё написанное - мои субъективные представления, подкрепленные небольшим опытом:

Цитата
Основная проблема - нет понимания, какие я должен совершить действия в ПЛИС, что бы, отправить или принять кусочек данных с/на хост?
Вот включили питание ПЛИС-прошивка загрузилась-хост определил устройство PCI-E и выделил ему кусок памяти в своем ОЗУ. После записал в ПЛИС (как я понимаю в регистр/память? BAR0 базовый адрес. Для чего остальные BAR1-BAR5 не доконца понимаю). На этом завершается инициализация устройства PCI-E в системе и оно готово читать/писать данные с/на хост. Если в чем-то я не прав поправьте.
Вот после инициализации, что я должен сделать, что бы начать отправку данных на хост или как я узнаю, что хост подготовил для ПЛИС данные?


Есть отличная книга Jackson M., Budruk R., PCI Express Technology. Comprehensive Guide to Generations 1.x, 2.x, 3.0. Идеально для понимания этой шины на все 100%. Очень простым языком написана. Но в этой книге нет ли слова как работать от хоста.

Дело в том, что шина PCI шлет так называемые TLP-пакеты. На самом деле это обычные примитивные пакеты, не сложнее любого протокола для RS-232. Там чуток полей. Адресация BDF - bus device function. Как правило, PCI ядра позволяют получить пользователю со стороны ПЛИС то, на какой BDF село устройство. Если BDF получателя 0 - значит пакет идет в хост. Там есть еще поле адрес. Оно 32 бита может быть.

Можно заполнять 32-бит адрес, поле данных - и всё это точно придет в хост. Но... будет отброшено. Чтобы хост не отверг наши данные надо выделить кусочек памяти в ядре (например 4096 байт). Этот кусочек будет иметь некий стартовый адрес - это просто. Но дело в том, что на шине PCI оно будет иметь другой адрес - это результат нелепого устройства архитектуры x86, но ради универсальности между ARM MIPS x86, драйвера используют самый универсальный механизм. И для этого задействуют API ядра Windows/Linux чтобы установить привязку этого кусочка в памяти ядра и его же но на шине PCI. Вызвав функцию, мы получим адрес этого кусочка на шине. Как только ПЛИС узнает этот адрес на шине PCI и пошлет на него пакет, то оно вскоре очутится в этой памяти, и данные прочитает драйвер.

Как же в ПЛИС попадет этот адрес? Достаточно лишь выслать эти 4 байта. Для этого есть BAR-адреса:
Код
00:14.2 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] SBx00 Azalia (Intel HDA)
        Subsystem: Micro-Star International Co., Ltd. [MSI] Device f641
        Flags: bus master, slow devsel, latency 64, IRQ 16
        Memory at fcff4000 (64-bit, non-prefetchable) [size=16K]

Видно что size=16K. Эти адреса примечательны тем, что вызвав пару команд в драйвере станет возможным затем вызывать в Linux readl/writel и таким образом обмениваться с устройством пакетами по 4 байта данных. Можно лишь по 4 байта за раз и это очень медленно. Но удобно чтобы прочитать регистр статуса или еще для чего то, например выслать адрес буфера.

Поэтому настроив работу через BAR, как в любом драйвере PCI, мы можем прислать 4 байта адреса в ПЛИС, и ПЛИС сможет писать в этот буферок пакетиками по 64/128/256 байт. И так за несколько пакетов заполнить весь буфер.

Но как хост поймет что ПЛИС заполнило буфер??? Для этого есть прерывания. В PCI-E есть очень удобный механизм MSI - message signaled interrupts. Это значит вместо дергания ножки, устройство высылает пакетик о том что случилось прерывания. Драйвер это увидит и проснется, чтобы скопировать данные пользователю, или что-то другое с ними сделать. Так работает механизм DMA. Все что я описал - это он и есть.

Я повторюсь, что всё это чудовищно просто. Надо лишь уловить суть этой примитивной логики работы PCI-E и DMA. Я год разбирался с этим всем делом. Но я возился не с тем что там всё сложно или мудрено. А возился именно с тем, чтобы выяснить что как надо делать. Сейчас я умею работать с PCI-E на Altera Lattice и Xilinx. Потому что освоив ПЛИС одного производителя, всё PCI-E ядра оказались очень похожими, хотя видно что их делали разные разработчики.

1) настраиваем BAR (можем читать-писать по 4 байта туда сюда) 2) выделяем блочек 4К и отображаем на PCI 3) регистрируем обработчик прерывания 4) шлем этот адрес через BAR 5) ПЛИС высылает серию 64 пакетов по 64 байта = 4096 6) ПЛИС дергает ножку MSI у PCI ядра 7) драйвер проснулся и готов работать с этими 4К данных от ПЛИС.

Вот пример моего драйвера - использовал для замера скорости записи от ПЛИС: http://paste.org.ru/?0bqfgq
AVR
Цитата
"1) настраиваем BAR (можем читать-писать по 4 байта туда сюда)" - я так понимаю, означает получение устройством базового адреса на шине PCIe от ОС. Этот адрес записывается в BAR?
"2) выделяем блочек 4К" - выделением занимется драйвер?
"и отображаем на PCI" т.е приводим соответствие адресов на шине PCIe адресам в ОЗУ хоста?
"3) регистрируем обработчик прерывания" не понял?кто этим занимается?драйвер?
"4) шлем этот адрес через BAR " какой этот адрес? и что значит "шлем этот адрес через BAR"?
"5) ПЛИС высылает серию 64 пакетов по 64 байта = 4096" т.е. объем переданных данных от ПЛИС к хосту равен объему выделеной в ОЗУ памяти. А если при выделенном объеме = 4096 байта, мне нужно чтобы
драйвер обработал, скажем 256 байт, я могу его пнуть раньше, чем заполнятся все 4096 байта?
"6) ПЛИС дергает ножку MSI у PCI ядра" это и есть механизм посылки специализированного сообщения прерывания? Если так, как мне инициировать передачу такого сообщения?

1) Эти адреса, если не ошибаюсь, назначает BIOS, либо ОС на ранних этапах запуска. Устройство просто говорит, хочу пару регионов на 4К и на 256К например. А уже при старте ОС либо BIOS смотрит где там лучше выделить в адресном пространстве. После того как выделится, драйвер может буквально несколькими командами получить эти адреса себе в распоряжение (MMIO) и общаться посылками от 1 до 4 байт по этим адресам с нужными смещениями. Я вижу роль этого MMIO и BARов в качестве "регистрового интерфейса" устройства, чтобы получать статусы, передавать что-то небольшое. Раз 4К регион/диапазон, значит 1024 слова по 4 байт могут быть адресованы.
2) Выделяет драйвер в пространстве адресов ядра - ну просто кусок памяти, обычный такой, чтобы хранить какие-то данные. Драйвер, выполнив волшебную комманду, сможет узнать по какому адресу будет "видеть" ПЛИС этот кусочек. Он может быть другим, он может меняться от запуска к запуску системы или драйвера. Вот через MMIO (пункт 1) мы и сообщим эти 4 байта адреса ПЛИСине, куда она может TLP пакеты присылать. И они будут записываться в ОЗУ и ядро эти данные увидит - а нам это и надо, чтобы драйвер от ПЛИС получал данные.
3) Драйвер регистрирует, что когда возникнет MSI прерывание 0, то чтобы вызывалась некоторая функция. А в этой функции можно пробуждать драйвер от ожидания новых данных. Данные можно отбросить, куда-то скопировать, передать в пользовательскую программу.
4) См. пункт 2 - если мы установили что наш кусочек 4К в ядре имеет некий адрес на шине (иной), то мы должны каким-то образом об этом сказать ПЛИСине. Лучше чем MMIO (пункт 1) для этого ничего нет.
5) Да, можно и раньше. Можно вообще только 4 байта прислать и пнуть - и вот они наши 4 байта прислались. Можно 8 байт и т.д. Главное не слать данные между границ страниц памяти, они могут быть 4К, а может иной размер быть настроен в ОС.
6) В любом ядре есть MSI вход. Достаточно просто фронтик на 1-битовом входе сделать и через некоторое время снять (обычно есть сигнал ACK для этого). А оно уже само пошлет что нужно и куда нужно.

Цитата
1.Как функционирует система в режиме gather-scatter? Как и кто формирует таблицу дескрипторов и на основании чего она формируется?где хранится?
2.В каких случаях лучше использовать режима gather-scatter, а в каких целесообразнее иной режим?
3.Если хост отправляет данные в PCIe устройство, то он сначала записывает весь объем данных к себе в ОЗУ, а потом пинает устройство и говорит - "данные готовы-забирай". Или же хост напрямую отправляет данные в устройство?
4.Есть ли механизмы переназначения адресов BAR без перезагрузки системы (например перезаливка прошвики ПЛИС без перезагрузки системы)?
5. Вы сказали, что имеете опыт работы с Альтерой может Вы знаете почему в примерах Alter-ы для Arria 10 нет доступа к BAR0, а BAR4 и выход DMA подключены к одной шине?и как инициировать передачу на хост для сборки Avalon-MM DMA?

1) Честно говоря, не использовал я этот scatter-gather. Если я не ошибаюсь, и правильно понимаю как это работает, я делаю аналог этого механизма своими руками.
Суть, видимо, вот в чем, не ручаюсь за 100% правильность. В пространстве ядра (не знаю как в процессорах с IOMMU) нет трансляции адресов вроде бы, стало быть проблема фрагментации стоит в полный рост. В общем случае, две последовательно идущие страницы памяти могут и не найтись, всё что гарантировано - это одна страница памяти (например 4К). Вот можно навыделять например 1024 таких разбросанных по адресам (scattered) страниц по 4К и получить нужные 4М памяти. Вот эти 1024 адреса можно прислать в ПЛИС и она будет заполнять одну за другой. Видимо дескриптор это мудреное название для записи в воображаемой таблице, где слева номер страницы (первая вторая ... последняя) а справа адрес 4 байта данного кусока по 4К (=1 стр памяти).
2) Какие иные режимы Вы знаете? sm.gif
3) Не могу подсказать, с отправкой потока данных в ПЛИС не работал. Но не обязательно всё сразу в драйвер из программы пользователя загребать. Можно и по частям. Но я чисто предполагаю что именно так - мы заполнили кусочки данными для ПЛИС и сказали ПЛИС - выгребай. И ПЛИС шлет пачку TLP запросов типа MRd (memory read + ожидание ClpD с данными в ответ).
4) Не знаю sm.gif Reset наше всё. Удобнее работать, когда устройство в еще один комп воткнуто. Оно ведь виснуть будет на первых порах, как же без этого sm.gif
5) С шиной Avalon не работал, равно как и PCI-E + Nios. Я использовал вариант ядра PCI-E без Nios. Все пакеты делал сам в своей логике. Так что не могу подсказать по тонкостям реализации Altera.
Хотя то, через что я работал, кажется звалось Avalon-ST (stream), довольно простой интерфейс. Но видимо сильно различается с MM.
dxp
AVR, а вы проводили функциональное моделирование в симуляторе вашего PCIe устройства? И по гайду сразу в синтез и оно работает без вопросов?

Я правильно понимаю, что ваша реализация - на Альтере? Какую микросхему использовали? Какие параметры линка (ген, ширина)? Каких скоростей удалось достичь? Или это вам было не нужно (трафик небольшой)?
AVR
Цитата(dxp @ Jun 9 2018, 06:12) *
AVR, а вы проводили функциональное моделирование в симуляторе вашего PCIe устройства? И по гайду сразу в синтез и оно работает без вопросов?

Что Lattice что Altera - PCI-E заработало без вопросов, без всяких моделирований. Хотя я оборачивал ядро во враппер, и моделировал логику работы самого устройства в Modelsim - так было удобнее, чем ковыряться в железе. Но по шине, повторюсь, никакой возни не было.

Цитата(dxp @ Jun 9 2018, 06:12) *
Я правильно понимаю, что ваша реализация - на Альтере? Какую микросхему использовали? Какие параметры линка (ген, ширина)? Каких скоростей удалось достичь? Или это вам было не нужно (трафик небольшой)?

Пока что скромно - 1.0 x1, скорость получал 170+ Мбайт/с от ПЛИС в хост.
dxp
А Flow Control как-то обрабатываете? Или трафик такой, что гарантировано проблем не возникает?
polyvyannyy
Цитата(AVR @ Jun 8 2018, 13:20) *
1) Эти адреса, если не ошибаюсь, назначает BIOS, либо ОС на ранних этапах запуска. Устройство просто говорит, хочу пару регионов на 4К и на 256К например. А уже при старте ОС либо BIOS смотрит где там лучше выделить в адресном пространстве. После того как выделится, драйвер может буквально несколькими командами получить эти адреса себе в распоряжение (MMIO) и общаться посылками от 1 до 4 байт по этим адресам с нужными смещениями. Я вижу роль этого MMIO и BARов в качестве "регистрового интерфейса" устройства, чтобы получать статусы, передавать что-то небольшое. Раз 4К регион/диапазон, значит 1024 слова по 4 байт могут быть адресованы.
2) Выделяет драйвер в пространстве адресов ядра - ну просто кусок памяти, обычный такой, чтобы хранить какие-то данные. Драйвер, выполнив волшебную комманду, сможет узнать по какому адресу будет "видеть" ПЛИС этот кусочек. Он может быть другим, он может меняться от запуска к запуску системы или драйвера. Вот через MMIO (пункт 1) мы и сообщим эти 4 байта адреса ПЛИСине, куда она может TLP пакеты присылать. И они будут записываться в ОЗУ и ядро эти данные увидит - а нам это и надо, чтобы драйвер от ПЛИС получал данные.
3) Драйвер регистрирует, что когда возникнет MSI прерывание 0, то чтобы вызывалась некоторая функция. А в этой функции можно пробуждать драйвер от ожидания новых данных. Данные можно отбросить, куда-то скопировать, передать в пользовательскую программу.
4) См. пункт 2 - если мы установили что наш кусочек 4К в ядре имеет некий адрес на шине (иной), то мы должны каким-то образом об этом сказать ПЛИСине. Лучше чем MMIO (пункт 1) для этого ничего нет.
5) Да, можно и раньше. Можно вообще только 4 байта прислать и пнуть - и вот они наши 4 байта прислались. Можно 8 байт и т.д. Главное не слать данные между границ страниц памяти, они могут быть 4К, а может иной размер быть настроен в ОС.
6) В любом ядре есть MSI вход. Достаточно просто фронтик на 1-битовом входе сделать и через некоторое время снять (обычно есть сигнал ACK для этого). А оно уже само пошлет что нужно и куда нужно.


1) Честно говоря, не использовал я этот scatter-gather. Если я не ошибаюсь, и правильно понимаю как это работает, я делаю аналог этого механизма своими руками.
Суть, видимо, вот в чем, не ручаюсь за 100% правильность. В пространстве ядра (не знаю как в процессорах с IOMMU) нет трансляции адресов вроде бы, стало быть проблема фрагментации стоит в полный рост. В общем случае, две последовательно идущие страницы памяти могут и не найтись, всё что гарантировано - это одна страница памяти (например 4К). Вот можно навыделять например 1024 таких разбросанных по адресам (scattered) страниц по 4К и получить нужные 4М памяти. Вот эти 1024 адреса можно прислать в ПЛИС и она будет заполнять одну за другой. Видимо дескриптор это мудреное название для записи в воображаемой таблице, где слева номер страницы (первая вторая ... последняя) а справа адрес 4 байта данного кусока по 4К (=1 стр памяти).
2) Какие иные режимы Вы знаете? sm.gif
3) Не могу подсказать, с отправкой потока данных в ПЛИС не работал. Но не обязательно всё сразу в драйвер из программы пользователя загребать. Можно и по частям. Но я чисто предполагаю что именно так - мы заполнили кусочки данными для ПЛИС и сказали ПЛИС - выгребай. И ПЛИС шлет пачку TLP запросов типа MRd (memory read + ожидание ClpD с данными в ответ).
4) Не знаю sm.gif Reset наше всё. Удобнее работать, когда устройство в еще один комп воткнуто. Оно ведь виснуть будет на первых порах, как же без этого sm.gif
5) С шиной Avalon не работал, равно как и PCI-E + Nios. Я использовал вариант ядра PCI-E без Nios. Все пакеты делал сам в своей логике. Так что не могу подсказать по тонкостям реализации Altera.
Хотя то, через что я работал, кажется звалось Avalon-ST (stream), довольно простой интерфейс. Но видимо сильно различается с MM.



Спасибо большое за столь развернутые ответы. Теперь буду приводить мысли в порядок и пробовать)Уверен, будут еще вопросы wink.gif
AVR
Цитата(dxp @ Jun 9 2018, 13:32) *
А Flow Control как-то обрабатываете? Или трафик такой, что гарантировано проблем не возникает?

Нужно следить за статусами "кредитов", т.е. емкости приемных буферов например ближайшего бриджа или непосредственно хоста - всё это PCI-E ядро само обновляет запросами и сообщает пользователю в ПЛИС. А со стороны драйвера просто такой трафик в моей задаче, что оно само собой разруливается, но в других ситуациях следить надо конечно.

Цитата
Спасибо большое за столь развернутые ответы. Теперь буду приводить мысли в порядок и пробовать)Уверен, будут еще вопросы

С радостью отвечу на все последующие вопросы, на какие смогу.
dxp
Цитата(AVR @ Jun 9 2018, 18:12) *
Нужно следить за статусами "кредитов", т.е. емкости приемных буферов например ближайшего бриджа или непосредственно хоста - всё это PCI-E ядро само обновляет запросами и сообщает пользователю в ПЛИС. А со стороны драйвера просто такой трафик в моей задаче, что оно само собой разруливается, но в других ситуациях следить надо конечно.

Да, вот меня больше волнует ситуация, когда не запись из ПЛИС на хост, а чтение потока данных из системной памяти в ПЛИС - нужно очень аккуратно выдавать запросы на запись, чтобы комлешны не забили входные буфера. Такие ситуации хотелось бы помоделировать. Только не очень понятно, каким образом эмулируется на функциональном моделировании физический уровень - ясно, что там нет смысла трансиверы изображать, но хотя бы их функциональность надо. В доках Xilinx упоминается некий PIPE - Physical Interface for PCI Express, который, вроде, и берёт на себя эту задачу. Но что это и как использовать, пока не знаю. Кто в курсе темы, поделитесь опытом, советами?
AVR
Цитата(dxp @ Jun 9 2018, 15:53) *
Да, вот меня больше волнует ситуация, когда не запись из ПЛИС на хост, а чтение потока данных из системной памяти в ПЛИС - нужно очень аккуратно выдавать запросы на запись, чтобы комлешны не забили входные буфера. Такие ситуации хотелось бы помоделировать. Только не очень понятно, каким образом эмулируется на функциональном моделировании физический уровень - ясно, что там нет смысла трансиверы изображать, но хотя бы их функциональность надо. В доках Xilinx упоминается некий PIPE - Physical Interface for PCI Express, который, вроде, и берёт на себя эту задачу. Но что это и как использовать, пока не знаю. Кто в курсе темы, поделитесь опытом, советами?

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

Иными словами, не собрались ли Вы бороться с несуществующей проблемой? sm.gif
Там все эти возможные стопоры и задержки естественным образом уходят. Или у x86 есть механизм, чтобы хост сам формировал запросы копирования из ОЗУ на шину?
Всё может быть, что я эту возможность упустил, хотя когда я спрашивал об этом у вроде как спецов, они такую возможность почему-то отвергали.
dxp
Проблема может возникнуть из-за того, что если накидать запросов на чтение - а такой запрос - это простейший TLP, состоящий из заголовка, - так, что в ответ будет валиться большое число комлешнов. По стандарту PCIe реквестер чтения должен заявлять бесконечное число кредитов для ответных комплешнов, поэтому хост будет пытаться честно наливать поток в соответствии с запросами. И если накидать таких запросов (non-posted транзакций), то в ответ повалится неслабая пачка CplD, которая забьёт буфера и всё обломается по таймауту.

Чтобы не доводить до этого, реквестер (ПЛИС) должен метать запросы, контролируя кредиты приёмника. Конечно, можно данные качать порциями - сделал запросы так, чтобы гарантировано не переполнились приёмные буфера, и пока их не вычерпал, новые не слать. Но тогда будет простой на шине и скорости не достичь. Поэтому тут нужно в динамике следить за кредитами и слать запросы так, чтобы и кредитов хватало, и пауз не было. Вот это представляется нетривиальной задачей и её бы хотелось погонять в симуляторе.
AVR
Цитата(dxp @ Jun 9 2018, 17:56) *
Но тогда будет простой на шине и скорости не достичь

Мне кажется, всё там как надо будет достигаться. Невелик простой. Столько сколько нужно.
AVR
Цитата
Подскажите пожалуйчта, как из пользовательской логики ПЛИС можно прочитать значение регистров BAR0 (1-5)?

Что такое значение регистров BAR и зачем его читать? https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%...D0%B2%D0%BE_PCI Base Address Register
От хоста просто приходит некий пакет. Некоторые (если не все) IP ядра дают сигнал типа bar hit - показывают, в какой именно BAR (если вообще попал) и его диапазон попал адрес из пакета. Но вообще-то, какой смысла устройству знать значение этого регистра? Этот адрес имеет значение для хоста, а не устройства. Пришел пакет например чтения, и у него есть смещение - значит мы понимаем что хотел хост.
Я может уже забывать начал, но мне никогда не надо было знать значение BAR непосредственно...
polyvyannyy
Цитата(AVR @ Jun 17 2018, 14:03) *
Что такое значение регистров BAR и зачем его читать? https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%...D0%B2%D0%BE_PCI Base Address Register
От хоста просто приходит некий пакет. Некоторые (если не все) IP ядра дают сигнал типа bar hit - показывают, в какой именно BAR (если вообще попал) и его диапазон попал адрес из пакета. Но вообще-то, какой смысла устройству знать значение этого регистра? Этот адрес имеет значение для хоста, а не устройства. Пришел пакет например чтения, и у него есть смещение - значит мы понимаем что хотел хост.
Я может уже забывать начал, но мне никогда не надо было знать значение BAR непосредственно...


А если ПЛИС инициирует запись в хост, как узнать какой адрес вставлять в заголовок TLP посылки?
doom13
Цитата(polyvyannyy @ Jun 18 2018, 12:53) *
А если ПЛИС инициирует запись в хост, как узнать какой адрес вставлять в заголовок TLP посылки?

Для этого в системе необходим драйвер (модуль ядра), который выделяет кусок памяти, передаёт адреса данной памяти в FPGA (настраивает DMA).
AVR
Цитата(polyvyannyy @ Jun 18 2018, 12:53) *
А если ПЛИС инициирует запись в хост, как узнать какой адрес вставлять в заголовок TLP посылки?

Мы ведь на тему BAR? Для этого придумали MSI-прерывания. Драйвер просыпается от прерывания и хост читает некий регистр, причем тогда, когда ему удобно. Лучше пусть хост будет мастером всех этих процессов. А прочитав статусный регистр устройства ему будет ясно, что нужно делать дальше.
RobFPGA
Приветствую!
Цитата(dxp @ Jun 9 2018, 15:53) *
...
Только не очень понятно, каким образом эмулируется на функциональном моделировании физический уровень - ясно, что там нет смысла трансиверы изображать, но хотя бы их функциональность надо. В доках Xilinx упоминается некий PIPE - Physical Interface for PCI Express, который, вроде, и берёт на себя эту задачу. Но что это и как использовать, пока не знаю. Кто в курсе темы, поделитесь опытом, советами?
В симуляции с PIPE в основном сложности с подключением веревок интерфейсов. Ну и некоторые нюансы с настройкой параметров для PCIe корки для работы с симуляцией PIPE (чтоб не ждать долго инициализации линка). К тому же у Xilinx немного разные наборы сигналов для разных версий PCIe. Ну и некоторые проблемы возникают при генерации корки. Если точнее то раньше можно было сгенерировать корку как обычно c MGT а потом уже при симе параметром выбирать интерфейс PIPE/MGT режим. А сейчас так не получается (на оптимизировали блин) либо генериш и симиш ее с PIPE, либо с MGT.
Если использовать для симуляции root-complex BFM такую же корку от Xilinx то особых проблем для коннекта с PIPE нет.

Например у меня такой вот шаблон для теста PCIe установленных на BD диаграммах.
CODE
// Full path to the tested PCIe end_point
`define EP_INST i_top.i_pcie_sys.i_xdma.inst.pcie3_ip_i.inst
`define EP_PIPE i_top.i_pcie_sys.i_xdma.inst.pcie3_ip_i

`ifdef _ENABLE_GT_
parameter PIPE_SIM = "FALSE";
defparam `EP_INST.EXT_PIPE_SIM = "FALSE";
defparam `EP_INST.PL_EQ_BYPASS_PHASE23 = "FALSE";
`else
parameter PIPE_SIM = "TRUE";
defparam `EP_INST.EXT_PIPE_SIM = "TRUE";
defparam `EP_INST.PL_EQ_BYPASS_PHASE23 = "TRUE";
`endif

// PCIe root-complex BFM (and path to the Xilinx root_complex PCIe instance)
`define RP_PIPE RP.i_rp_tb.i_axi_pcie3
root_complex_bfm #(.PIPE_SIM(PIPE_SIM), ...) RP(.pcie_clk_p(rp_clk_p), ..., mgt_rx_p(rp_rx_p[0]), ..., mgt_tx_p(rp_rx_p[0]), ...);
...
if (PIPE_SIM=="TRUE") begin
initial begin
force `EP_PIPE.common_commands_in =`RP_PIPE.common_commands_out;
force `EP_PIPE.pipe_rx_0_sigs =`RP_PIPE.pipe_tx_0_sigs ;
...
force `RP_PIPE.common_commands_in =`EP_PIPE.common_commands_out;
force `RP_PIPE.pipe_rx_0_sigs =`EP_PIPE.pipe_tx_0_sigs ;
...
end
end
// tested BD module
pcie_sys i_pcie_sys (.pcie_clk_p(rp_clk_p), ..., mgt_rx_p(rp_tx_p[0]), ..., mgt_tx_p(rp_rx_p[0]), ...);
...
initial begin
RP.rp_bfm.reset();
wait (RP.rp_bfm.init_complete);
...
end

Ну а если PCIe BFM сторонний то надо будет мудрить с адаптером PIPE.

Удачи! Rob.

dxp
Спасибо за ответ, прошу прощения за паузу, не был готов задавать вопросы.

Цитата(RobFPGA @ Jun 18 2018, 18:30) *
В симуляции с PIPE в основном сложности с подключением веревок интерфейсов. Ну и некоторые нюансы с настройкой параметров для PCIe корки для работы с симуляцией PIPE (чтоб не ждать долго инициализации линка). К тому же у Xilinx немного разные наборы сигналов для разных версий PCIe. Ну и некоторые проблемы возникают при генерации корки. Если точнее то раньше можно было сгенерировать корку как обычно c MGT а потом уже при симе параметром выбирать интерфейс PIPE/MGT режим. А сейчас так не получается (на оптимизировали блин) либо генериш и симиш ее с PIPE, либо с MGT.
Если использовать для симуляции root-complex BFM такую же корку от Xilinx то особых проблем для коннекта с PIPE нет.


Вот тут начинаются непонятности. Изучение темы PIPE привело к следующему: PIPE - есть промежуточный внутренний интерфейс (придуманный Интелом) между MAC и физическим уровнем, некий аналог MII/GMII/SGMII и прочих для изернета. И хотя он называется PIPE - Physical Interface for PCI Express, он же используется и для USB, DisplayPort и других высокоскоростных сериальных интерфейсов (понятно, что в каждом случае со своими особенностями).

Т.е. это не какой-то виртуальный отладочный интерфейс, но вполне реальный, боевой. Он может быть как внешним, когда, например, к ПЛИС цепляется внешняя микросхема PCIe PHY (видел дизайн на Spartan3 + NXP PCIe PHY), так и внутренним - удобно передавать между вендорами и на уровне IP ядер в ASIC'остроении.

Понятно, что если решение монолитное, т.е. одна микросхема, в которой всё, то этот PIPE, если он там есть, является внутренним интерфейсом и наружу не высовывается за ненадобностью. Но в ряде случаев его можно использовать для отладки. Например, логичным выглядит при моделировании в симуляторе исключить из оного MGT блоки, которые, во-первых, сложны и эта сложность никак не помогает при функциональном моделировании, а только мешает, во-вторых, работают на высоких частотах, что будет сильно грузить симулятор совершенно без профита. Т.е. соединить тестируемые блоки напрямую через их PIPE интерфейсы, минуя MGT.

Вроде так, поправьте, если неверно понял.

Так вот, учитывая вышесказанное, просится задействовать PIPE для моделирования. В настройках PCIe IP ядра есть следующая опция:

Нажмите для просмотра прикрепленного файла

о чём в доке (PG054) коротко и просто сказано:

• None: No PIPE mode simulation is available. This is the default value.

• Enable Pipe Simulation: When selected, this option generates the core that can be simulated with PIPE interfaces connected. This option is enabled for both Endpoint and Root Port configurations only when the Shared Logic (clocking) in example design option is selected (see Shared Logic, page 234).

• Enable External PIPE Interface: When selected, this option enables an external third-party bus functional model (BFM) to connect to the PIPE interface of the Integrated Block for PCIe. This feature has been tested only with BFM from Avery Design Systems (XAPP1184 [Ref 21]). For more information, see PIPE Mode Simulations, page 264.

Самое непонятное со вторым пунктом. Вроде сказано, что в этом случае рожается "core that can be simulated with PIPE interfaces connected". Но при этом никаких изменений в портах ядра по сравнению с вариантом None не видно. Где там PIPE интерфейс, которые можно законнектить с ответной частью? Что понимается под PIPE simulation?

Такой интерфейс появляется в третьем случае, про который прямо сказано, что это для коннекта с "external third-party bus functional model". Изучая ваш шаблон, пришёл к выводу, что вы-то как раз этот вариант и используете. Или нет? Судя по сигналам, таки да. sm.gif Но тогда не понятно, откуда взялась BFM от Xilinx для этого варианта, если они сами отсылают к сторонним. Кстати, апноту, а которой они отсылают (XAPP1184), изучил, там всё более-менее понятно, только вот самой модели тоже нет и ссылка к ней [очевидно, давно] протухла. Да и не больно-то и хотелось. sm.gif

Я пробовал все три варианта. Во всех случаях соединение идёт через GT, время прогона одинаковое. Т.ч. по факту оно ни на что не влияет. Что-то сделал не так?

Правильно ли я понял про

Цитата(RobFPGA @ Jun 18 2018, 18:30) *
В симуляции с PIPE в основном сложности с подключением веревок интерфейсов.


что тут речь идёт именно о третьем варианте (Enable External PIPE Interface), где нужно потроха pipe_tx/rx_n_sigs и common_commands_in/out раскидать на правильные сигналы и подключить их к ответной стороне?

Цитата(RobFPGA @ Jun 18 2018, 18:30) *
Ну и некоторые нюансы с настройкой параметров для PCIe корки для работы с симуляцией PIPE (чтоб не ждать долго инициализации линка)

А можно поподробнее: что тут конкретно делается?

Ну, и про симулятор. Каким вы пользуетесь? Вообще и в частности для моделирования PCIe. Компиляция библиотеки для PCIe хочет зашифрованный файл из secureip, и это вызывает сложности с использованием сторонних симуляторов совместно с современной версией Vivado (текущая хочет Model/Questasim 10.6с, которого не найти).

И последний вопрос: есть ли какие-либо проблемы с синтезатором? Ну, например, на одних версиях работает, на других нет? Периодически вижу, как народ жалуется, что вот выходит новая версия вивады/квартуса, и проект перестаёт собираться и/или работать. Вы на какой версии успешно это синтезировали?
RobFPGA
Приветствую!
Цитата(dxp @ Jul 10 2018, 13:11) *
...
Вроде так, поправьте, если неверно понял.
Да так и есть - PIPE это некая спецификация для коннекта между Logic layer и Phy Layer.

Цитата(dxp @ Jul 10 2018, 13:11) *
Так вот, учитывая вышесказанное, просится задействовать PIPE для моделирования. В настройках PCIe IP ядра есть следующая опция: ...
Уточните версию софта - судя по картинке это гдето 2016.*
Цитата(dxp @ Jul 10 2018, 13:11) *
...
2 Enable Pipe Simulation: When selected, this option generates the core that can be simulated with PIPE interfaces connected. This ...
3 Enable External PIPE Interface: When selected, this option enables an external third-party bus functional model (BFM) to connect ...
Самое непонятное со вторым пунктом. Вроде сказано, что в этом случае рожается "core that can be simulated with PIPE interfaces connected". Но при этом никаких изменений в портах ядра по сравнению с вариантом None не видно. Где там PIPE интерфейс, которые можно законнектить с ответной частью? Что понимается под PIPE simulation?
Это как раз та "сложность" подключения веревок" Как я понял все это безобразие - так как PIPE интерфейс нужен
был только для симуляции то Xilinx изначально не рассчитывал вытягивать веревки наружу корки. А цеплял симулятор через жо.. механизм force напрямую через иерархию. При этом сама корка была "правильной" с точки зрения RTL дизайна - все top параметры корректно меняли структуру корки - то есть можно было сгенрить корку - воткнуть ее в RTL и меняя параметр PIPE_SIMULATION получать симуляцию с PIPE или GTE - красота! Потом добавили опцию генерации внешних PIPE веревок для унификации интерфейсов. Потом судя по всему концепция поменялась sad.gif и начиная с какой то версии (и какой то матери) параметр PIPE_SIMULATION на топе корки ни на что не влияет. Так как часть структуры корки меняется при генерации корки скриптом напрямую в RTL!. Поэтому сейчас - блин - приходится генерить отдельно для симуляции - отдельно для P&R crying.gif И получается фигня - то есть веревки интерфеса PIPE - то их нет. И что? каждый раз менять TB?

Цитата(dxp @ Jul 10 2018, 13:11) *
Такой интерфейс появляется в третьем случае, про который прямо сказано, что это для коннекта с "external third-party bus functional model". Изучая ваш шаблон, пришёл к выводу, что вы-то как раз этот вариант и используете. Или нет? Судя по сигналам, таки да. sm.gif
И да и нет. Так как изначально я цеплялся к PIPE вариантом force - так как PCIe у меня не всегда близко к топу дизайна то мне лень страдать вытаскиванием PIPE интереса наружу. Поэтому такой вот шаблон - куда бы нелегкая не занесла PCIe я поменяв путь к ней в `define подключусь к висящим там PIPE веревкам.
Цитата(dxp @ Jul 10 2018, 13:11) *
Но тогда не понятно, откуда взялась BFM от Xilinx для этого варианта, если они сами отсылают к сторонним. Кстати, апноту, а которой они отсылают (XAPP1184), изучил, там всё более-менее понятно, только вот самой модели тоже нет и ссылка к ней [очевидно, давно] протухла. Да и не больно-то и хотелось. sm.gif
Эта BFM взялась из отвращения "уважения" к тому примеру который дает Xilinx wink.gif Сейчас внутри это обычная AXI-PCie bridge (x8 gen3) корка в режиме root-complex к которой прикручен писаный на sv BFM имитирующий работу CPU. С основными прибамбасами по инициализации PCIe, BAR, чтению/записи регистров, системной памяти, обработке прерываний, XDMA, и.т.д. Была мысль прикрутить через DPI прослойку для отладки софта и драйверов. Я как то пытался прикручивать к PIPE внешную BFM DrivExpress - и даже заработала - но функционал оказался бякой.

Цитата(dxp @ Jul 10 2018, 13:11) *
Я пробовал все три варианта. Во всех случаях соединение идёт через GT, время прогона одинаковое. Т.ч. по факту оно ни на что не влияет. Что-то сделал не так?
А это как раз "некоторые нюансы" с настройкой параметров для PCIe - То что корка была сгенерирована с PIPE интерфейсом это не значить что она готова с ним работать wacko.gif Надо подправить некие внутренние параметры модулей чтобы PIPE заработал wink.gif как раз это и делается через defparam...
Цитата(dxp @ Jul 10 2018, 13:11) *
Правильно ли я понял про
что тут речь идёт именно о третьем варианте (Enable External PIPE Interface), где нужно потроха pipe_tx/rx_n_sigs и common_commands_in/out раскидать на правильные сигналы и подключить их к ответной стороне?
А можно поподробнее: что тут конкретно делается?
Это больше 2 чем 3 вариант. Для 3 нужно вытягать шины наружу в TB и подключать их как обычные порты.
Force позволяет подключится к цепи внутри дизайна вместо имеющегося источника. То есть когда сгенерировал на BD корку с PIPE интересом но никуда его не подключил то Vivado по умолчанию на неподключенные входы цепляет 0. Force отцепляет этот 0 и подключает ко входам выходы PIPE из root-complex BFM.
Цитата(dxp @ Jul 10 2018, 13:11) *
Ну, и про симулятор. Каким вы пользуетесь? Вообще и в частности для моделирования PCIe. Компиляция библиотеки для PCIe хочет зашифрованный файл из secureip, и это вызывает сложности с использованием сторонних симуляторов совместно с современной версией Vivado (текущая хочет Model/Questasim 10.6с, которого не найти).
Пользую QuestaSim 10.4e. Сейчас смотрю что и как с 18.2 Вроде компилирует - но есть всего 1 ошибка при компиляции как раз в XDMA. Как мне кажется пока не связанная с криптованием.
Цитата(dxp @ Jul 10 2018, 13:11) *
И последний вопрос: есть ли какие-либо проблемы с синтезатором? Ну, например, на одних версиях работает, на других нет? Периодически вижу, как народ жалуется, что вот выходит новая версия вивады/квартуса, и проект перестаёт собираться и/или работать. Вы на какой версии успешно это синтезировали?
Для Xilinx я успешно синтезировал начиная с версии ISE 3.1 вроде sm.gif C PCIe в Vivadо работаю с 14 версии. В железе вроде все работает. Как раз синтезатор в Vivado относительно неплох. Хоть раньше я в основном пользовался Synplify (да и сейчас периодически смотрю в нем что и как получается) но особой необходимости заменить им вивдовский пока не было.
Vivado пока еще сыровато и многое меняется как в интерфейсе так и структуре. И в любой версии есть свои глюки. Поэтому хочется стабильности - миришся с тем что есть, манять новые плюшки - тянешь проекты вперед. Если лень (и можеш себе позволить ) - держишь зоопарк версий. Сейчас у меня в основном работа на 17.4 и немного на 15.3 и 17.1.

Успехов! Rob.
dxp
Цитата(RobFPGA @ Jul 10 2018, 20:54) *
Уточните версию софта - судя по картинке это гдето 2016.*

Самая что ни на есть 2018.2. sm.gif Это для 7-Series FPGA, возможно для более толстых семейств вид уже другой.

Цитата(RobFPGA @ Jul 10 2018, 20:54) *
Это как раз та "сложность" подключения веревок" Как я понял все это безобразие - так как PIPE интерфейс нужен
был только для симуляции то Xilinx изначально не рассчитывал вытягивать веревки наружу корки. А цеплял симулятор через жо.. механизм force напрямую через иерархию. При этом сама корка была "правильной" с точки зрения RTL дизайна - все top параметры корректно меняли структуру корки - то есть можно было сгенрить корку - воткнуть ее в RTL и меняя параметр PIPE_SIMULATION получать симуляцию с PIPE или GTE - красота! Потом добавили опцию генерации внешних PIPE веревок для унификации интерфейсов. Потом судя по всему концепция поменялась sad.gif и начиная с какой то версии (и какой то матери) параметр PIPE_SIMULATION на топе корки ни на что не влияет. Так как часть структуры корки меняется при генерации корки скриптом напрямую в RTL!. Поэтому сейчас - блин - приходится генерить отдельно для симуляции - отдельно для P&R crying.gif И получается фигня - то есть веревки интерфеса PIPE - то их нет. И что? каждый раз менять TB?

Я правильно понял, что раньше (совсем раньше) было две опции: None и Enable PIPE Simulation, и при генерировании example project сам Xilinx уже выполнял подключение RP и EP обоими способами - и через GT, и через PIPE (путём force), только при None параметр PIPE_SIMULATION был FALSE, а при Enable PIPE Simulation этот параметр становился TRUE, что автоматически переключало поток между RP и EP по тому или иному пути, а для юзера всё было вообще просто и шоколадно?

И уже несколько позже добавили третью опцию Enable External PIPE Interface, которая выводила сигналы PIPE наружу модуля - не очень понятно зачем, если так всё было просто и удобно. А потом вообще убрали внутреннее подсоединение PIPE через force, и теперь приходится самому вручную геморроиться, генерируя два несовместимых варианта корки - при None получатся годная для синтеза, но бесполезная для симулятора (т.к. внутри нет доступных PIPE сигналов), а при Enable PIPE Simulation и Enable External PIPE Interface получается негодная для синтеза (из-за лишних несинтезируемых сигналов), но подходящая для симулятора. Так?

Или вторая опция (Enable PIPE Simulation) вообще пустая (меняет только никому не нужный параметр PIPE_SIMULATION), а реально работают только первая (для синтеза) и третья (для симулятора). А вторая опция по сути даёт то же что и первая. Так?

Цитата(RobFPGA @ Jul 10 2018, 20:54) *
Эта BFM взялась из отвращения "уважения" к тому примеру который дает Xilinx wink.gif Сейчас внутри это обычная AXI-PCie bridge (x8 gen3) корка в режиме root-complex к которой прикручен писаный на sv BFM имитирующий работу CPU. С основными прибамбасами по инициализации PCIe, BAR, чтению/записи регистров, системной памяти, обработке прерываний, XDMA, и.т.д.

Вы сами её написали или перепилили тот вариант, что идёт вместе c example project? Я посмотрел, там очень немало кода, с нуля такое написать - надо иметь очень много свободного времени и неслабое желание. sm.gif

И что вызвало "уважение" sm.gif к примеру от Xilinx? Что-то не работало или просто сделано всё так, что неюзабельно?

Цитата(RobFPGA @ Jul 10 2018, 20:54) *
А это как раз "некоторые нюансы" с настройкой параметров для PCIe - То что корка была сгенерирована с PIPE интерфейсом это не значить что она готова с ним работать wacko.gif Надо подправить некие внутренние параметры модулей чтобы PIPE заработал wink.gif как раз это и делается через defparam...

Посмотрел в вашем шаблоне, там только два параметра настраиваются:

Код
  defparam `EP_INST.EXT_PIPE_SIM         = "FALSE";
  defparam `EP_INST.PL_EQ_BYPASS_PHASE23 = "FALSE";


Это просто для примера или этого достаточно? Так понял, что первый параметр рулит, выдавать ли PIPE интерфейс наружу, а второй... похоже, что управляет включением/выключением какой-то инициализационной фазы. У моей корки такого параметра нет, но есть такой:

Код
parameter PL_FAST_TRAIN       = "FALSE", // Simulation Speedup


возможно, это аналог - включает/выключает быструю тренировку линка. Оно?

Цитата(RobFPGA @ Jul 10 2018, 20:54) *
Это больше 2 чем 3 вариант. Для 3 нужно вытягать шины наружу в TB и подключать их как обычные порты.
Force позволяет подключится к цепи внутри дизайна вместо имеющегося источника. То есть когда сгенерировал на BD корку с PIPE интересом но никуда его не подключил то Vivado по умолчанию на неподключенные входы цепляет 0. Force отцепляет этот 0 и подключает ко входам выходы PIPE из root-complex BFM.

Резюмируя, какую опцию вы используете для синтеза (None или Enable PIPE Simulation) и для симулятора (Enable PIPE Simulation или Enable External PIPE Interface)?

Цитата(RobFPGA @ Jul 10 2018, 20:54) *
Пользую QuestaSim 10.4e. Сейчас смотрю что и как с 18.2 Вроде компилирует - но есть всего 1 ошибка при компиляции как раз в XDMA. Как мне кажется пока не связанная с криптованием.

Да, подтверждаю, 10.4e решает проблему (ранее была 10.4a). Вивада выдаёт предупреждение, что версия не та, но дальше всё работает - это означает, что в этой версии есть подходящий ключ для дешифрования.

Попутно выяснилась подлая штука: оказывается, что если компилировать либы для одного семейства, то компилирует он не все, а только часть, при этом модель, используемая в выбранной FPGA, тем не менее ссылается на файлы, которые не попали в компиляцию. Выход: при компиляции невзирая указывать -family all. Подробнее тут.

Ну, и сделал прогон тестового проекта на вивдовском симуляторе и на квесте. Результат:

Vivado: 8:46
Questa: 1:12

Соотношение 1:7.3. Вот так вот. Ну, и вообще, вивадовский сим совсем какой-то неповоротливый - он и компиляет, и элаборацию делает в примерно такое же время раз дольше, чем квеста. Такое впечатление, что он целиком (и движок тоже) на жабе написан. Или на тикле. sm.gif

P.S. Кстати, не оценивали, какая разница в скорости прогона при коннекте через GT и через PIPE? Сколько там - проценты или разы? Стоит ли морочиться с PIPE в реальности? И если даже при подключении RP и EP через PIPE путём force поток идёт мимо GT, сами-то трансиверы никуда не делись - они же как объекты остались и работают на своей скорости (гигагерцы), а значит должны сожрать производительность симулятора. Или не так - т.е. если у них отобрать поток данных (через force), то они просто болтаются там в статике и никому не мешают?


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

Цитата(dxp @ Jul 11 2018, 15:04) *
Я правильно понял, что раньше (совсем раньше) было две опции: None и Enable PIPE Simulation, и при генерировании example project сам Xilinx уже выполнял подключение RP и EP обоими способами - и через GT, и через PIPE (путём force), только при None параметр PIPE_SIMULATION был FALSE, а при Enable PIPE Simulation этот параметр становился TRUE, что автоматически переключало поток между RP и EP по тому или иному пути, а для юзера всё было вообще просто и шоколадно?
Да так и есть (вернее было).

Цитата(dxp @ Jul 11 2018, 15:04) *
И уже несколько позже добавили третью опцию Enable External PIPE Interface, которая выводила сигналы PIPE наружу модуля - не очень понятно зачем, если так всё было просто и удобно. А потом вообще убрали внутреннее подсоединение PIPE через force, и теперь приходится самому вручную геморроиться, генерируя два несовместимых варианта корки - при None получатся годная для синтеза, но бесполезная для симулятора (т.к. внутри нет доступных PIPE сигналов), а при Enable PIPE Simulation и Enable External PIPE Interface получается негодная для синтеза (из-за лишних несинтезируемых сигналов), но подходящая для симулятора. Так?
Да - Если включаеш любую опцию Enable PIPE Simulation скрипт при генерации корки вырезает кусок RTL для синтеза. И наоборот.
Может это и поправили в 18 версии но пока некогда ковырятся проверять.
Цитата(dxp @ Jul 11 2018, 15:04) *
Или вторая опция (Enable PIPE Simulation) вообще пустая (меняет только никому не нужный параметр PIPE_SIMULATION), а реально работают только первая (для синтеза) и третья (для симулятора). А вторая опция по сути даёт то же что и первая. Так?
Нет - 2 и 3 это одно и тоже - только 3 еще и внешний порт создает чтобы с force не мучатся.

Цитата(dxp @ Jul 11 2018, 15:04) *
Вы сами её написали или перепилили тот вариант, что идёт вместе c example project? Я посмотрел, там очень немало кода, с нуля такое написать - надо иметь очень много свободного времени и неслабое желание. sm.gif
И что вызвало "уважение" sm.gif к примеру от Xilinx? Что-то не работало или просто сделано всё так, что неюзабельно?
Сам. В основном время ушло на разбор что нужно, что и как делаетя в примерах работы с PCIe Xilinx (и Алтера тоже). Ну и несколько вариантов разных.
Код у Xilinx старый - видно что писан еще во времена голого verilog отсюда такая громоздкая структура.
А хотелось чтобы для user было типа такого -
Код
cs_rp_bfm rp_bfm; //RP bfm class
cs_cpu cpu_bus;    //CPU bus class
initial begin
  rp_mem_api =new("RP_API",i_ddr_axi_mc_sim.axi_mem); // API to system memory
  rp_cfg_local  =new("RP_cfg_local");  // API to RP local configuration space read/write
  // RP BFM root_complex
  rp_rc_bfm    =new("RP root-complex", rp_cfg_local, rp_mem_api, ...);
  ...
  rp_rc_bfm.system_reset();
  rp_rc_bfm.rp_init();
  rp_rc_bfm.rp_enumerate();
  $display("[%t] : Root-port initialization done ...",$time);
end

task test_ep0 ...
  rev_date =new("REV_DATE",  RP.cpu_bus, rp_rc_bfm.ep[0].bar[0]+REV_DATE_ADDR, "0x%08x"); // endpoint register
  rev_date.display(); // rev_date.set(..),  rev_get.get(..), ...


Цитата(dxp @ Jul 11 2018, 15:04) *
Посмотрел в вашем шаблоне, там только два параметра настраиваются:
Это просто для примера или этого достаточно? Так понял, что первый параметр рулит, выдавать ли PIPE интерфейс наружу, а второй... похоже, что управляет включением/выключением какой-то инициализационной фазы. У моей корки такого параметра нет, но есть такой:
Этого достаточно для работы с AXI-PCIe bridge и с PCie XDMA, Для работы с чисто PCIe не скажу точно - давно не работал но должно быть похоже так как i_uut.i_pcie_sys.i_xdma.inst.pcie3_ip_i это обычная голая PCIe корка.
Для синтеза и сима с GT* опция None, для сима с PIPE -Enable external PIPE.

Цитата(dxp @ Jul 11 2018, 15:04) *
Попутно выяснилась подлая штука: оказывается, что если компилировать либы для одного семейства, то компилирует он не все, а только ...
Вот как раз запустил в 18.2 сим XDMA с PIPE - Оказалось что предварительная компиляция корки в библиотеку и компиляция BD в проекте идет с разными параметрами внутренних интерфейсов поэтому при запуске валится сим если последовательность библиотек для поиска модулей сначала находит корку в предварительно скомпилированной библиотеке sad.gif. Ну а вообще вивадовская каша с библиотеками это отдельный "плач Ярославны"

Цитата(dxp @ Jul 11 2018, 15:04) *
P.S. Кстати, не оценивали, какая разница в скорости прогона при коннекте через GT и через PIPE? Сколько там - проценты или разы? Стоит ли морочиться с PIPE в реальности? И если даже при подключении RP и EP через PIPE путём force поток идёт мимо GT, сами-то трансиверы никуда не делись - они же как объекты остались и работают на своей скорости (гигагерцы), а значит должны сожрать производительность симулятора. Или не так - т.е. если у них отобрать поток данных (через force), то они просто болтаются там в статике и никому не мешают?
Разница в разы - когда включен PIPE симулятор то GT убираются из структуры корки полностью.

Успехов! Rob.

dxp

Цитата(RobFPGA @ Jul 11 2018, 20:31) *
Сам. В основном время ушло на разбор что нужно, что и как делаетя в примерах работы с PCIe Xilinx (и Алтера тоже).

Снимаю шляпу! sm.gif А чем всё-таки штатный пример не устроил? Там вроде бы тоже RP сделан на той же корке в режиме Root Complex, и типа "прикладной код" написан, который выполняет всю работу - енумерацию, передачу и приём TLP. Код, конечно, местами некрасиво написан - чего стоит только компоновка через `include, но это, имхо, можно малой кровью переформатировать.

Цитата(RobFPGA @ Jul 11 2018, 20:31) *
Да - Если включаеш любую опцию Enable PIPE Simulation скрипт при генерации корки вырезает кусок RTL для синтеза. И наоборот.
Может это и поправили в 18 версии но пока некогда ковырятся проверять.
Нет - 2 и 3 это одно и тоже - только 3 еще и внешний порт создает чтобы с force не мучатся.


Цитата(RobFPGA @ Jul 11 2018, 20:31) *
Этого достаточно для работы с AXI-PCIe bridge и с PCie XDMA, Для работы с чисто PCIe не скажу точно - давно не работал но должно быть похоже так как i_uut.i_pcie_sys.i_xdma.inst.pcie3_ip_i это обычная голая PCIe корка.
Для синтеза и сима с GT* опция None, для сима с PIPE -Enable external PIPE.


Я немного запутался: так вы используете вариант с force или с внешними портами?

Цитата(RobFPGA @ Jul 11 2018, 20:31) *
Вот как раз запустил в 18.2 сим XDMA с PIPE -

Там компиляция этой корки валится с ошибками - что-то там на языковые конструкции жалуется? Как вы это обошли?

Цитата(RobFPGA @ Jul 11 2018, 20:31) *
Разница в разы - когда включен PIPE симулятор то GT убираются из структуры корки полностью.

Я все три варианта прогнал "из коробки", все вяжутся через GT. В каком случае оно GT убирает полностью? Когда defparam'ами установишь значения параметров?
RobFPGA
Приветствую!
Цитата(dxp @ Jul 12 2018, 07:35) *
Снимаю шляпу! sm.gif А чем всё-таки штатный пример не устроил? Там вроде бы тоже RP сделан на той же корке в режиме Root Complex, и типа "прикладной код" написан, который выполняет всю работу - енумерацию, передачу и приём TLP. Код, конечно, местами некрасиво написан - чего стоит только компоновка через `include, но это, имхо, можно малой кровью переформатировать.
Лучший способ разобраться что и как - переписать все по-своему. Я и начал с "малой крови" делая врапперы над этим франкинштейном и переписывая все более менее модульно на SV. В результате получился свой монстрик sm.gif Потом появился AXI-PCIe bridge и стало немного проще если не надо работать на уровне TLP.

Цитата(dxp @ Jul 12 2018, 07:35) *
Я немного запутался: так вы используете вариант с force или с внешними портами?
У меня PCie корки в основном ставятся на BD. Корку для сима генерирую с Enable External PIPE Interface но порты ext_pipe наружу BD не вытягиваю они висят в BD не подключенные. И цепляюсь к ним из TB через force. Для P&R перегенерирую корку с NONE при этом не надо ничего больше править на BD.

Цитата(dxp @ Jul 12 2018, 07:35) *
Там компиляция этой корки валится с ошибками - что-то там на языковые конструкции жалуется? Как вы это обошли?
Пока благородя помощи efq из темы про microblaze_v10 sm.gif

Цитата(dxp @ Jul 12 2018, 07:35) *
Я все три варианта прогнал "из коробки", все вяжутся через GT. В каком случае оно GT убирает полностью? Когда defparam'ами установишь значения параметров?
Ну да - defparam *.inst.pcie3_ip_i.inst.EXT_PIPE_SIM = "TRUE"|""FALSE; как раз отключает/включает GT PHY внутри PCie корки.
Код
module rp_tb_i_axi_pcie3_0_pcie3_ip_pcie3_uscale_core_top ...
  parameter EXT_PIPE_SIM = "FALSE",  // This Parameter has effect on running PIPE simulation by dis-connecting GTs and synthesis by connecting GTs.


Удачи! Rob.
dxp
Цитата(RobFPGA @ Jul 12 2018, 13:58) *
Лучший способ разобраться что и как - переписать все по-своему. Я и начал с "малой крови" делая врапперы над этим франкинштейном и переписывая все более менее модульно на SV. В результате получился свой монстрик sm.gif Потом появился AXI-PCIe bridge и стало немного проще если не надо работать на уровне TLP.

Понятно. И сколько времени ушло на это? Или сложно оценить, т.к. делалось постепенно, от проекта к проекту, пока не вырисовалось более-менее удобоваримое и полностью управляемое своё?


Цитата(RobFPGA @ Jul 12 2018, 13:58) *
У меня PCie корки в основном ставятся на BD. Корку для сима генерирую с Enable External PIPE Interface но порты ext_pipe наружу BD не вытягиваю они висят в BD не подключенные. И цепляюсь к ним из TB через force. Для P&R перегенерирую корку с NONE при этом не надо ничего больше править на BD.

Ага, теперь почти совсем понятно. А почему вторую опцию не используете (Enable PIPE Simulation), раз всё равно внешний PIPE интерфейс не юзается, а просто болтается в воздухе - какой смысл его генерить? По ходу, вторая опция была бы как раз именно то, что и надо. Не так?

Цитата(RobFPGA @ Jul 12 2018, 13:58) *
Пока благородя помощи efq из темы про microblaze_v10 sm.gif

На уровне исходников поправили?
RobFPGA
Цитата(dxp @ Jul 12 2018, 10:17) *
Понятно. И сколько времени ушло на это? Или сложно оценить, т.к. делалось постепенно, от проекта к проекту, пока не вырисовалось более-менее удобоваримое и полностью управляемое своё?
Да - это был не отдельный таск. В общем возился где-то месяца 3-4 в фоновом режиме, разбираясь со всем что есть для PCIe и переписывая пример Xilinx. Вариант с AXI-PCie bridge в основном сделал где-то за месяц.

Цитата(dxp @ Jul 12 2018, 10:17) *
Ага, теперь почти совсем понятно. А почему вторую опцию не используете (Enable PIPE Simulation), раз всё равно внешний PIPE интерфейс не юзается, а просто болтается в воздухе - какой смысл его генерить? По ходу, вторая опция была бы как раз именно то, что и надо. Не так?
Уже и не вспомню. Там все что то менялось с сигналами для разных версий PCie и разных чипов. Да и разницы нет - главное как-то устаканилось в методике применения.

Цитата(dxp @ Jul 12 2018, 10:17) *
На уровне исходников поправили?
Нет - вариант от efq компилируется без этой ошибки. Причем по коду непонятно что как может вызывать эту ошибку в оригинале.

Удачи! Rob.
dxp
Цитата(RobFPGA @ Jul 12 2018, 14:40) *
Да - это был не отдельный таск. В общем возился где-то месяца 3-4 в фоновом режиме, разбираясь со всем что есть для PCIe и переписывая пример Xilinx. Вариант с AXI-PCie bridge в основном сделал где-то за месяц.

...

Уже и не вспомню. Там все что то менялось с сигналами для разных версий PCie и разных чипов. Да и разницы нет - главное как-то устаканилось в методике применения.

Ну, в первом приближении всё стало куда понятнее и прозрачнее. Спасибо вам огромное за внятные и исчерпывающие ответы, очень помогли сориентироваться в обсуждаемом вопросе!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.