Search the Community
Showing results for tags 'pcie'.
-
Добрый день. Столкнулся с интересной ситуацией. Аппаратная часть: плата zcu102, диск формата M.2, переходник PCIe (для подключения M.2), SD карта. Программы: petalinux 2019.1, vivado 2019.1. Проект: на основе bsp (zcu102) + hdf-файл (custom) Краткое описание процесса "погружения": 1. Загрузчик (SD карта) + rootFS (SD карта) => всё ОК. 2. Загрузчик (SD карта) + rootFS (M.2 диск, вставленный в PCIe разъём zcu102) => всё OK. 3. Загрузчик (QSPI) + rootFS (SD карта) => всё ОК. 4. Загрузчик (QSPI) + rootFS (M.2 диск, вставленный в PCIe разъём zcu102) => ПРОБЛЕМА: nwl-pcie fd0e0000.pcie: Link is DOWN и далее приблизительно такой текст: Waiting for root device /dev/nvmeb0p1 после которого загрузка прекращается. В интернете предложены пути решения проблемы "nwl-pcie fd0e0000.pcie: Link is DOWN". Я попробовал некоторые решения, которые не привели к успеху, например: 1. Сброс, как здесь https://www.mail-archive.com/[email protected]/msg07127.html 2. Сброс, как здесь (вариант c перекомпиляцией fsbl) https://support.xilinx.com/s/question/0D52E00006iHlZrSAK/zynq-ultrascale-pcie-root-port-lessons-learned?language=en_US Может быть дело не в сбросе?! Есть ещё, на мой взгляд, "мистические" варианты, например вот этот (я не пробовал): https://support.xilinx.com/s/question/0D52E00006hpNMVSA2/zcu102-no-pcie-link-up?language=en_US Помогите, пожалуйста, разобраться. Что можно ещё попробовать (предпринять)?
-
есть плата с ПЛИС (Xilinx | US+) втыкаемая в хост через PCIe, в ПЛИС предполагаю что-то типа XDMA с доступом через PCIe к внутренностям системы (PCIe-AXI) на этой ПЛИС хотелось бы развернуть Линукс (то есть моя задача сделать такую платформу для программистов) программисты хотят иметь какой-то быстрый (широкополосный) и стандартный способ доступа к этому Линуксу (пока они утверждают, что NFS only - так как на некой отладочной плате они так работали) на хосте тоже Линукс ------------------------- у меня пока нет понимания, что можно сделать, чтобы такое заработало. писать какие-то коды для линукс-хоста (типа эмуляция эзернет через PCIe) хотелось бы как можно меньше ------------------------ если не NFS, то какие варианты? может есть что-то уже готовое от того же ксайлинса - положил через какую-то программку на хосте - достал на таргете (и наоборот) еще эмулятор последовательного порта через PCIe-XDMA надо или что-то подобное, чтобы на таргете терминал работал...
-
PCIe и Cyclone 4 GX
Ilya_Msk99 posted a topic in Работаем с ПЛИС, области применения, выбор
Всем привет! Появилась задача поднять PCIe на FPGA (на руках плата с Cyclone 4 GX). Сложности возникают абсолютно на всех стадиях. Сгенерировать Hard IP согласно документации Intel вроде и получается, однако даже со сборкой проекта огромное количество проблем, так как из-за не понимая интерфейса IP ядра не понятно что с чем соединять (очевидно что за информацией нужно идти в альтеровскую документацию на IP ядро, но из-за недостатка опыта не получается вытащить от туда необходимую информацию). Также сложность заключается в том, что почти все проекты в свободном доступе для Xilinx. Буду рад любой помощи от более опытных разработчиков: проекты, ссылки, описания и т д. -
Компания I-PEX разработала разъёмы с Paddle-Card для применения на скоростях до 56 Гбит/с –PAM4/PCIe Gen6 PAM4. Разъёмы и сборки могут работать в корпоративных вычислительных системах, которым требуется высокоскоростная передача, таких как серверы, коммутаторы, хранилища. Подробнее
-
- pcie
- разъемы l1nk
-
(and 3 more)
Tagged with:
-
Продолжаю осваивать Vivado на Xilinx (пока с огромной натяжкой). Есть некая система: мастер PCIe -> AXI interconnect -> 5 слейвов (регистры, память, Jesd и прочее). У каждого слейва свой адрес на шине AXI (выровнял адреса до старших бит, для более простой дешифрации) Ну далее всё просто, беру в настройках корки, каждому бару присваиваю базовый адрес какого либо из слейвов, назначаю размер и всё норм. Через программу верхнего уровня спокойно читаю/пишу по каждому бару связанный с ним слейв. Проблема в том, что я ограничен 6-ю барами (в дальнейшем нужно будет больше слейвов). Решил попробовать простое решение, расширить один из баров в два раза и просто обращаться через него к последовательно стоящим друг за другом слейвам. Ну по логике, думаю, когда кончится адресное пространство первого, интерконнект должен перескочить на второй и работать уже с ним. Но не так-то всё просто, IP ядро PCIE почему то заворачивает адресное пространство на начало первого слейва и снова работает с ним, только сначала. К такому финту я не был готов.. Читал, искал инфу пока ничего не нашёл. Почему ядро так делает и как от этого можно избавиться? Сталкивался кто нибудь с такой проблемой? Буду очень благодарен разъяснениям =)
- 19 replies
-
- interconnect
- xilinx
-
(and 2 more)
Tagged with:
-
Добрый день. Долго работал с Intel (Altera) бед не знал в среде Quartus и вот пришлось перейти (к глубокому сожалению) на работу с Xilinx... Сразу был разочарован, многое из того, что доведено до автоматизма у Intel тут нужно делать самому, вникая в низкоуровневые тонкости. Очень большие ограничения на использования ip-ядер (плюс скудный набор изменяемых параметров) и плохие тайминги заводят меня в тупик. Так вот, какова суть проблемы. Работаю с Kintex Ultrascale. Понадобилось собрать систему из ядра PCIe -> interconnect ->DDR4. Прочитал кучу мануалов (PG194 v3.0, PG059 и тд.., Ответы с форумов, Видео пример настройки, Вивадовские примеры). В общем собрал систему похожую на систему из примеров. Рис. 1 Тут добавил ещё Jtag консоль для удобства отладки (в дальнейшем необходимо заменить её на свой блок ДМА), вывел интерфейсы для своих слейвов наружу. ДДР тоже вывел наружу (как S_DDR) на верхнем уровне закольцевал и вернул обратно (как M_DDR, опять же дикость связанная с XILINX пришлось решать одну из его проблем таким образом). Повесил ещё пару ИЛА для отладки и отображения шины АXI. Назначил адресные пространства. Рис. 2 Вроде всё задышало. Но с большими слеками на интерконнекте... То PCIe сама развестись не может, то на ядре ДДР какие то проблемы по таймингам. В общем всё плохо, но как то работает. По PCIe есть доступ и к DDR и к регистрам в слейвах, вроде всё корректно. Начинаю работать через Jtag консоль (в дальнейшем её нужно заменить своим блоком ДМА) и всё, ДДР не читается не пишется, комп умирает, интерконнект виснет. Проблема только при обращении к ДДР, при работе с моими слейвами регистровыми проблем нет, данные корректно пишутся и читаются. Залез по ИЛА и увидел что от ДДР не доходит сигнал BVALID и BID через интерконнект. Собственно из ДДР он вышел, но через интерконнект до второго мастера он не приходит, а для первого без проблем, всегда всё хорошо. Окей, меняю местами Jtag и PCIe та же шляпа. Jtag работает корректно, до PCIe не доходит BVALID и BID. Получается что второму мастеру по счёту просто не даётся доступ к ДДР. Листал форумы, читал советы, нашёл. Говорят что на Ultrascale и Ultrascale+ стандартный интерконнект не работает корректно, нужно ставить некий "SMARTCONNECT"... Ну окей.. читаю документацию, разбираюсь, вставляю смартконнект.. А у него оказывается выкидывает все ID(r/w/b) на шине AXI. Чтобы ID не выкидывались, ставьте "axi sideband" (говорит XILINX) до и после интерконнекта на каждой шине.. окей, поставил. Спустя все эти манипуляции я получил рабочую схему, которая может работать с двумя мастерами и без проблем читать и писать в ДДР. Рис. 3 Но эта штука разводится очень плохо. Сложность в том, что у AXI PCIe максимальная частота 250МГц, у ДДР в моём режиме (1200МГц частота памяти) AXI DDR 300МГц. Слейвы свои на такой частоте я не потяну, иначе вообще всё по таймингам умрёт... пришлось ставить в 2 раза меньше. Поставил 150МГц на слейвах. В итоге интерконнект городит очень сложную структуру из ядер клоковых конвертеров, конвертеров данных, протоколов и тд.. А потом при имплементации на эти же ядра и ругается Вивадо. Долго бьюсь над этой проблемой, не могу нормально побороть слеки. Пришлось понизить частоту ДДР до 1000МГц, соответственно AXI DDR стала 250Мгц, а частота моих слейвов 125 МГц. Слеки явно улучшились, работать можно, но проблема совсем не ушла. Как мне правильно настроить систему, чтобы не было конфликтов между ядер XILINX и всё нормально разводилось при требуемых параметрах?
- 17 replies
-
- xilinx
- ultrascale
-
(and 4 more)
Tagged with:
-
Собственно задача - с минимальными потерями времени и усилий работать с хоста через PCI-E с ускорителем в ПЛИС. Насколько я понял самый простой способ - использование ядра XDMA (обёртка над ядром PCI-E) [1], готовых драйверов xdma.ko [2] и шаблонов приложений которые идут в комплекте [3] Но после вдумчивого изучения pg195 и запуска на плате тестового примера остались вопросы, хотя они скорее системного плана, но связаны именно со спецификой ядра XDMA. Что надо от ускорителя (для определенности - пусть будет крипто-ускоритель): 1) "стримить" с хоста данные на обработку, притом чтобы ускоритель мог сообщать, что достаточно, пока больше не надо присылать данные (т.е. некий flow control на отправку) 2) уведомлять хост о том, что данные обработаны и можно забирать, и соответственно отдавать "стрим" в хост. Почему стрим в кавычках: по сути это не непрерывный стрим, а блоки по 4К (притом с заголовками, чтобы на приёмной стороне (хосте) можно было сматчить контекст - какому выходному блоку какой входной соответствовал), но по природе обработки ускоритель это как PIPE: с одной стороны вышло, с другой вышло и есть некая "глубина" внутри - чтобы начал выдавать первые данные надо несколько десятков блоков в него "застримить". Т.о. в терминах xdma для этой задачи AXI Stream подходит очень хорошо, но вот на тестовом проекте заметил нестабильную работу AXI Stream (пропадание данных) в связи с чем рассматриваю и AXI MM как альтерантиву. Но что бы написать "правильное" и надёжно работающее хостовое приложение хотелось бы понимать несколько вещей (далее список вопросов): ##### BAR ##### pg195, таблица 3, соответствующа вкладка в конфигураторе XDMA * DMA - это собственно работа с самим движком * Bypass DMA - думал что это прямой доступ к пространству памяти карточки в обход движка ДМА, но похоже это не так, это ЕЩЕ ОДНО выделенное адресное пространство (доп.канал) никак не связанное ни с движком ДМА ни с памятью в которую пишет движок ДМА. * AXI Lite Master - видимо от Bypass DMA отличается только тем, что это Lite 1.1 Смущает то, что для BAR DMA в режиме AXI MM в конфиге вивадо никак не задаётся размер BAR - это как?.. где/чем определяется размеры адресного пространства с которым работает карточка? 1.2 Далее в разделе про прерывания вскользь упомянуто, что BAR может быть _address space_ а может быть и _register space_. Надо ли держать это в уме или при использовании готового драйвера просто работать с /dev/xdma0_xxx и не париться? 1.3 Какие реальные кейсы могут быть для использования Bypass DMA ? ##### IRQ & user app ##### У самого IP-ядра есть внешние ножки прерывания, но как их использовать pg195 ответа не даёт, ограничиваясь тестовым примером проекта, в котором прерывания взводятся записью из хостовой программы в регистр в пространстве AXI Lite Master. Но как это обработать из хостовой программы совершенно неясно: 2.2 Вот мы открыли /dev/xdma0_h2c и льём туда данные, как считать прерывание "BUSY", что дескать лить хорош уже (и дальше ждать прерывания "FREE") - как это на стороне пользователя обрабатывать? 2.2 При приёме мы открываем /dev/xdma0_c2h и ждём прерывания "READY" указывающее на готовность данных в /dev/xdma0_c2h - как это на стороне пользователя обрабатывать? 2.3 Чем "правильнее" пользоваться на стороне карточки - ножками usr_irq_req и usr_irq_ack, или же механизмом MSI (msi_enable, msi_vector_width)? 2.4 В AR654444 еще описан способ загрузки драйвера в режиме поллинга (работает только в направлении c2h) - стоит ли использовать его вместо прерывания для упощения логики приложения? ##### AXI ST ##### Самое интересное: управление потоками, нарезка на "пакеты" DMA H2C Stream -------------- For host-to-card transfers, data is read from the host at the source address, but the destination address in the descriptor is unused. Packets can span multiple descriptors. The termination of a packet is indicated by the EOP control bit. A descriptor with an EOP bit asserts tlast on the AXI4-Stream user interface on the last beat of data. - т.е. на стороне хоста за формирование для AXI4-Stream сигнала tlast, который фактически нарезает пакеты как мне надо, отвечает отвечает механизм, выставляющий бит EOP (в TLP???) 3.1 достаточно ли для user app указать size=4K, для формирования EOP в xdma.ko? 3.2 см. пп.1.1 если мы не задали размер BAR для DMA, то кто будет заботиться о буферах в движке DMA на карточке и в пользовательском РТЛ коде? Буферы в движке DMA на карточке вообще черный ящик: вот отправим мы пакет с size=1М - куда его сохраняет движок DMA? - не налету же он его в пользовательскую логику передаёт??? 3.3 по размерам нашёл такое упоминание в PG195, эти значения как-то завязаны на размер внутренних буферов движка ДМА??: DMA C2H Stream -------------- For card-to-host transfers, the data is received from the AXI4-Stream interface and written to the destination address. Packets can span multiple descriptors. The C2H channel accepts data when it is enabled, and has valid descriptors. As data is received, it fills descriptors in order. When a descriptor is filled completely or closed due to an end of packet on the interface, the C2H channel writes back information to the writeback address on the host with pre-defined WB Magic value 16'h52b4 (Table 10: C2H Stream Writeback Fields), and updated EOP and Length as appropriate. - тут вроде бы тоже всё прозрачно - нарезаем пакаты для отправки сигналом tlast в AXI4-Stream, который по идее должен устанавливать в дескрипторе поле EOP 3.4 Удаляет ли при приёме дескриптор с WB Magic драйвер xdma.ko или же его должно удалять пользовательское приложение? 3.5 не очень понятна строка "For valid data cycles on the C2H AXI4-Stream interface, all data associated with a given packet must be contiguous" - означает ли это, что до взведения tlast надо держать tvalid и лить данные без пропуска клоков (иначе движок ДМА "отрежет" и отправит пакет на хост по таймауту)? ##### AXI MM ##### 4.1 опять см. пп.1.1 - как задаётся размер пространства для AXI MM? В интерфейсе конфигурирования нет такой настройки. ##### источники ##### [1] https://www.xilinx.com/support/documentation/ip_documentation/xdma/v4_1/pg195-pcie-dma.pdf [2] https://github.com/Xilinx/dma_ip_drivers [3] https://github.com/Xilinx/dma_ip_drivers/tree/master/XDMA/linux-kernel/tools
- 46 replies
-
- pcie
- pciexpress
- (and 8 more)
-
Всем привет! Artix7 Vivado 2019.1 Debian10 Собрал систему Axi Memory Mapped to Pci Express, CDMA, DDR3. Задача в том что бы посылать данные через PCIe в DDR с помощью DMA. В данный момент с ПК данные записываются в DDR ПЛИСа со скоростью 500Мб/с, что для заданных целей проекта мало. В ip PCIe у меня выделено 3 бара: DDR,BRAM, регистры CDMA. Всё прекрасно пишется и читается, но как я сказал выше, медленно. Так же в этой коре выделен один AXI BAR с адресом 0x40000000, который транслируется в адресное пространство CDMA как BAR0 PCIe'са и имеет адрес 0x60000000. Написал простенький дравер на линикс под данные цели, где заполняю регистры DMA. Адрес назначения = 0x80000000 (это адрес ddr в адресном пространстве cdma) и адрес источника который возвращает драйвер как выделенную память под dma, затем устанавливаю количество байт, что активирует трансфер из сорса в адрес назначение и в идеи данные из буфера выделенного драйвером в ПК должны появиться в ddr ПЛИС, но их там нет. Если сорс адрес ставить bram, то по той же схеме через драйвер, данные передаются из brem в ddr. Не могу понять что упускаю... pdf блок диаграммы, настройки и драйвей под линукс прикрепил. Можно попросить посмотреть файлы? Может кто нибудь подскажет что я не правильно делаю. PS не нашел ответов в и в Xilinx Answer 65062 AXI Memory Mapped for PCI Express Address Mapping design_1.pdf test_pci.c настройки и адреса.pdf
-
PCI Express Gen3 to Gen4
NDPaw posted a topic in ISA/PCI/PCI-X/PCI Express
Здравствуйте, уважаемые форумчане! Я в PCI-e новичок. Встала передо мной такая задача: нужно преобразовать поток данных от двух PCI Express Gen3 устройств (каждое х8) в один поток данных Gen4 также по x8 линиям. То есть соединить два устройства со скоростями Gen3 в одно со скоростью Gen4. Можно ли это сделать в принципе без кастомных FPGA-узлов? Может есть спец микросхемы? -
Проблемы с PCIE3.0 Tandem у KCU105
g700 posted a topic in Работаем с ПЛИС, области применения, выбор
Всем привет! Возникла проблема в конфигурации FPGA в режиме PCIE3.0 Tandem у отладочной платы KCU105. В проекте есть светодиод (led 0 на плате), который при второй стадии загрузки (по PCIE3.0) должен включатся. Порядок действий: Собираю проект design example. Констрейны для bitstream: После сборки генерирую MCS командой: Прошиваю конфигурационную память скриптом который есть в архиве program_spi.tcl Выключаю хост. Потом включаю. После загрузки вижу девайс: Читаю регисры с помощью mcap версия bitstream совпадает с ожидаемой. Прошиваю второй стадией: Поле прошивки ядро выдает сообщеие: После этого светодиод не горит, а mcap говорит: А если прошить FPGA по JTAG первой стадией, затем сделать reboot и прошить mcap воторой стадией, то светодиод горит и сообщения в ядре по irq нет. Данное IRQ принадлежит: Память конфигурационная память прошивается, через JTAG бластер по разъему J3. Версии: Vivado v2019.1 (64-bit) Хост в котором карточка Linux 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux Утилиты MCAP взята отсюда https://www.xilinx.com/support/answers/64761.html Ревизия KCU105 C Версия pci-utils pciutils-3.3.1 пробовал и с 3.6.3 одинаковый результат. В чем может быть проблема? pcie3_ultrascale_0_ex.zip- 6 replies
-
- xilinx
- ultrascale
-
(and 2 more)
Tagged with:
-
Вопрос не в том, можно ли так по правилам (читай - стандартам), а в том - можно ли от них и насколько отходить. Итак: дифференциальный RefClk частотой 100МГц надо заводить на каждый PCI-E target, основная цель, я так понимаю - чтобы у мультигигабитных трансиверов был исходный клок с одним и тем же дрейфом. Вопрос: а можно ли не заводить, а генерить локально? в сети разные мнения, от Note that the pcie bus ref clock needs to be common between all devices communicating on the pcie bus. До https://www.xilinx.com/support/answers/18329.html с техникой Asynchronous Clocking Также есть такая вот картинка: которая вроде бы говорит, что такое вроде как приемлемо, но хотелось бы ответа практиков. Зачем это всё? Есть девборда с Xilinx US/US+ c FMC но без PCI-E слота, сейчас появилась необходимость работать с PCI-E самая простая и материально незатратная идея реализовать это: изготовить райзер из FMC в PCI-E (через тот же USB3.0 кабель, которй используется китайцами повсеместно для выноса с материнки PCI-E 1х ). Но вот незадача - на FMC разведены мультигигабитные трансиверы, но задающий клок для них распаян локально на плате (номинал может программироваться во внешней фапч), резать дорожки, куда-то там подпаиваться - такой кейс совсем исключён. Поэтому для принятия решения о райзере хотелось бы заручиться уверенностью что заработает хотя бы в лабораторных условиях (в продакшене это использоваться не будет). (лабораторных условиях == температура 25С, что должно снизить разбос задающих частот на разных концах MGT)/ PCIe-Clock-Source-Selection.pdf
-
Flow control PCI Express AXI Spartan 6
vitaly_n posted a topic in ISA/PCI/PCI-X/PCI Express
Всем привет! Прошу помощи. Кто-нибудь знает, как правильно пользоваться сигналами fc_* из ядра PCIe? Вообще суть проблемы такая. Имеется плата с Spartan 6 45T. Firmware предоставляет регистры для записи-чтения по инициативе процессора (как memory), через них задаётся, что делать. Потом firmware делает запросы к памяти (DMA). Я реализовал flow control по четвёртому методу DATA_FC из UG672. Значения Total_CplH и Total_CplD брал, как рекомендовано, из таблицы E-1 (для моего случая 32 и 256 соответственно), хотя там дальше говорится: In the case where infinite credits have been advertised to the Link Partner for a specific Credit pool, such as Completion Credits for Endpoints, the user application should use this value along with the methods described in Appendix E, Managing Receive-Buffer Space for Inbound Completions to avoid completion buffer overflow. И до поры, до времени всё работало замечательно, но вот я нарвался на то, что передача данных затыкается при работе с процессорным модулем ComExpress - запросы из FPGA MEMORY_READ ушли, а ответов на них не пришло. Подозреваю, что у этого модуля более суровые ограничения на число запросов в очереди. Решил посмотреть на то, какие значения выставляются на fc_ph, fc_pd, fc_nph, fc_npd, fc_cplh и fc_cpld для разных значений fc_sel в разные моменты времени. Должен сообщить, что значения эти выглядят странными и непонятными, причём, я не нашёл какого-то внятного user guide, чтобы там объяснялось, как этими сигналами правильно пользоваться для целей flow control. Например, для fc_sel=000 (Receive Credits Available Space) значения такие: fc_ph = 32, fc_pd = 211, fc_nph = 8, fc_npd = 8, fc_cplh = 40, fc_cpld = 211 (Крайне смущают очень маленькие значения для fc_nph и fc_npd.) для fc_sel=100 (Transmit Credits Available Space) значения такие: fc_ph = 12, fc_pd = 80, fc_nph = 12, fc_npd = 1, fc_cplh = 0x7F, fc_cpld = 0x7FF (в соответствии с таблицей 5-17 из UG672 значения 0x7F и 0x7FF обозначают Infinite credits available). Я правильно понимаю, что мне надо взять fc_nph = 8, fc_npd = 8 вместо 32 и 256 для Total_CplH и Total_CplD? -
PCIe Gen3 PHY
kex posted a topic in Языки проектирования на ПЛИС (FPGA)
Подскажите, пожалуйста, видел ли кто-либо где-либо реализацию 128b/130b (8GT/s, Gen3+) PCIe PHY? Решил попробовать написать свою PCI корку для работы с хостом, т.к. не устраивает скорость работы хардварного альтеровского IP. -
Зависание при записи в BAR
new123 posted a topic in Работаем с ПЛИС, области применения, выбор
Форумчане, доброй ночи. Подскажите, может кто сталкивался. Бьюсь третий день. 1) Развернул корку на Stratix V, PCIE avalon 256bit + DMA 2) пытаюсь драйвер сделать, ничего не идет. 3) Что выяснил. При попытке записать что то в BAR0, BAR4, вешается компьютер. Ровно после тридцать девятой попытки записи четырех байт происходит зависание. При это сразу считываю, что там записалось, а ничего ничего не записалось. 4) Jungo Wizard пишет что BAR0, BAR locked. В Jungo так же пытаюсь записать и сразу прочитать. Не записывает значения. Уже начинаю склоняться, что то с альтерой или коркой. Может кто сталкивался с такой проблемой. -
Распиновка кабеля PCIe
alexadmin posted a topic in Компоненты
Смотрю сейчас на кабели PCIe (Samtec в частности) и возник дурной вопрос: я правильно понимаю, что для случая когда с обеих сторон Edge Connector, все сигналы как переворачиваются? То есть то что было на стороне A одного разъема, оказывается на B на другом и наоборот? Никогда раньше дела с такими не имел, наверное это подразумевается, но явно не написано https://www.samtec.com/products/pciec http://suddendocs.samtec.com/catalog_english/pciec.pdf