Ядро PCI-express в ПЛІС Achronix

PCIe

У ПЛІСSpeedster22i HD1000є два апаратні ядраPCIe, сертифікованихPCI-SIGна відповідність специфікаціїPCIe 3.0, а в налагоджувальній платіSpeedster22i HD1000 Development Kit(про яку я писав у попередньому пості) одне з цих ядер виведено наPCIeроз'єм. Через інтерфейсPCIeдуже зручно здійснювати взаємодію налагоджувальної плати з хост-комп'ютером. По суті це єдине високошвидкісне рішення для зазначеної мети. Альтернативою використанняPCIeдля зв'язку налагоджувальної плати з хост-комп'ютером може бути лише вбудований com-порт, який на кілька порядків повільніший. Всі інші рішення вимагають більших чи менших апаратних витонченостей, як мінімум, потрібно застосування перетворювачів рівня сигналу. У компаніїAchronixє референс-дизайн, що демонструє роботу апаратного ядраPCIeу всій красі – ядро ​​працює в режиміtargetз доступом як безпосередньоCPU, і через механізмDMAз читання і записи. Я перевірив, чи все працює відмінно. Але цей дизайн виявилося досить складно модифікувати під власні цілі через недостатню модульність і надмірну ускладненість коду мовоюVerilog. Тому було прийнято рішення на основі фірмового дизайну створити власний варіант, прибравши з нього все, пов'язане з обміном через DMA , а так само структурувавши його таким чином, щоб явно виділити в ньому модулі з незмінним кодом і модулі, код яких потрібно модифікувати для адаптації до конкретних завдань розробника. В результаті вийшов простий, добре структурований проект, адаптація якого під конкретні завдання розробника зводиться до нескладної зміни кодулише одного модуля. Фірмовою особливістюПЛІС Achronixє наявність апаратно реалізованих IP-ядер контролерів таких інтерфейсів, якPCIe,DDR3,100/40/10G EthernetтаInterlaken. Ці апаратні ядра забезпечують все, що потрібно для функціонування зазначених інтерфейсів, тільки що потрібно від розробника - написати власні модулі сполучення з цими контролерами. В результаті обсяг роботи драматично скорочується. Крім того, суттєво спрощується досягнення необхідного таймінгу. У разі дизайнуPCIe, знадобилося лише кілька модулів сполучення, причому більшість із них було взято з фірмового референс-дизайну.

Короткий опис проекту

У проекті реалізовано доступ до трьох 128-розрядних регістрів.PCIeядро ​​налаштовано на 3 BARа: BAR0 – 64KB, BAR1 та BAR2 – по 8 KB. Доступ до регістрів здійснюється через BAR1. Наявність 3х BARів зумовлено вимогами сумісності з драйвером, що використовується. Опис регістрів наводиться нижче:

Ім'я Зміщення до АП BAR1 тип Опис
R00RO>
R120hRW RWБіти [7:0] - виведення на лінійку світлодіодів Біти [127:8] - не використовуються
R240hRO RWБіти [7:0] – читання лінійки вимикачів Біти [127:8] – не використовуються

При модернізації проекту перше, що було зроблено - видалено код, пов'язаний з обміном даними через DMA. Після цього для підключення до ядра були використані канали читання та записуtarget_readтаtarget_write. Далі, було визначено структуру модулів, зображену малюнку:

achronix

Усього вийшло 4 модулі (вдеякі з них входять підмодулі)

Склад модулів:

  • pcie_g3x4.v- обгортка апаратного ядраPCIe. Визначає параметри, такі якVendorID, кількість смуг (lanes), ширину локальної шини і т. д. Цей модуль генерується за допомогою генератора ядер середовища розробкиACE.
  • pci_target_bus_ctrl.v– модуль обгортка, що узгоджує каналtargetапаратного ядра і локальну шину, на якій розташовані регістри, доступні через шинуPCI. Оскільки каналtargetскладається з двох незалежних підканалів: запису та читання, цей модуль об'єднує в собі два модулі:pci_target_bus_write_ctrl.vіpci_target_bus_read_ctrl.v, що реалізують операції запису та читання відповідно.
  • lbus_registers.v- модуль, що містить власне регістри користувача. Єдиний модуль вимагає модифікації коду під конкретний проект.
  • ACX_SNAPSHOT.v– допоміжний модуль для внутрішньосхемного налагодження. Після закінчення налагодження може бути виключено з проекту.

У цьому проекті для досягнення необхідної розробнику функціональності потрібно змінити вихідний код всього одного модуля -lbus_registers.v. Всі інші модулі при цьому використовуються як є, без жодної ситуації. При цьому модульlbus_registers.vможе використовуватися як шаблон, який додається необхідна розробнику функціональність. Таким чином, щоб отримати працюючий інтерфейс з кількома регістрами на шиніPCIe, потрібні витрати часу на дописування коду модуля не більше години.

Генерація ядра PCIe

Для генерації ядра можна скористатися генератором ядер ACE оболонки. Усі задані параметри зберігаються у файлі з розширенням .axip, який у будь-який момент можна.редагувати. Результатом роботи генератора є текстові файли мовамиVerilogтаVHDL. Знімок екрану в процесі генерації ядра показано на малюнку:

PCIe

Інтерфейс target ядра pcie

Локальна шина

Локальна шина має дуже просту структуру. Вона складається з двох незалежних каналів – запису та читання і може бути налаштована на різну ширину слова. У цьому проекті використовуються слова завширшки 128 біт. Інтерфейс локальної шини, реалізований у модуліlbus_registers.vзабезпечує запис у регістри без затримки та читання із затримкою на 1 такт. Реальні затримки, проте, трохи більше, т.к. підмодулі, що входять до модульpci_target_bus_ctrl.vроблять свій внесок у латентність транзакцій запису та читання.

Імплементація

Імплементація проекту складається з двох етапів – етапу синтезу та етапу трасування.

Структура каталогів

Для імплементації було обрано таку організацію каталогів:

У каталозі syn знаходиться файл проектуpcie_simple_design.prj. Цей файл необхідно вказати програмі синтезуsynplify-pro, розробленої компанієюSynopsys. Результатом роботи цієї програми є файлpcie_simple_design.vmaу підкаталозіsyn/rev_1. Цей файл є вхідним для наступного етапу – трасування. Знімок екрана під час виконання етапу синтезу показаний нижче:

pci-express

Трасування

Етап трасування здійснюється програмоюACEвласної розробки компаніїAchronix. У каталозіtrзнаходиться файл проектуpci-simple.prj, який треба вказати програміACE. Після закінчення етапу трасування в підкаталозіtr/impl_1/outputз'явиться файл прошивкиpci-simple-design.jam, який завантажуєтьсябезпосередньо в ПЛІС. Знімок екрану в процесі виконання етапу трасування:

ядро

Констрейнт

Є всього два файли констрейнтів – один визначає тактові ланцюги, а інший визначає використовувані піни вводу-виводу. Файли знаходяться в каталозіtrі мають іменаpcie_simple_design.sdcтаpcie_simple_design.pdcвідповідно. Вони вже підключені через файли проектів до програм синтезу та трасування.

Результати

Результати трасування
Frequency (MHz)
Clock/GroupTargetAchievedMeets Timing
user_clk212.5308.5yes (+45.2%)
core_clk212.5433.5yes (+104.0%)
sbus_clk50.0138.7yes (+177.5%)
Tck10.0175.4yes (+1653.6%)

Нас цікавить тактова група user_clk, на яку підключені регістри користувача. Як видно, при заданій частоті 212.5 MHz було досягнуто результату 308.5 MHz, тобто. на 45% вище, ніж потрібно.

Утилізація

Ресурс Зайнято
RLBs0.520%
LUT4 Sites0.410%
DFF Sites0.520%
MUX2 Sites0.010%
ALU Sites0.170%
LRAM Sites1.280%
BRAM Sites0.190%
BMULT Sites0.000%
I/O Pad Sites1.980%
Data Pads1.740%
Clock Pads12.50%
Reset Pads0.000%

Підключення до хост-комп'ютера

Для підключення до хост-комп'ютера потрібен драйвер. За певних умов можна використовувати драйвер із фірмового референс-дизайну. З цим драйвером працює програмаPciExpress.exe, через яку можна звертатися до регістрів, підключених до шиниPCIe. Щоб можна було використовувати ці засоби, потрібно зберегти структуру BARів оригінального дизайну та зберегти значення параметрівVendorIDтаDeviceID.

Щоб почати працювати з хост-комп'ютером з операційною системою Windows, необхідно виконати такі дії:

  • Підключити налагоджувальну плату до комп'ютера через шинуPCIe. Потрібен слот PCIe x8 або ширший. З'єднання слід проводити на вимкнених пристроях з дотриманням заходів антистатичного захисту. Відлагоджувальну плату запитати від зовнішнього джерела живлення.
  • Увімкнути живлення комп'ютера та плати. Порядок включення живлення несуттєвий.
  • Завантажити у ПЛІС прошивку.
  • За допомогою менеджера пристроїв виявити новий пристрій на шиніPCIі встановити драйвер.
  • Перезавантажити
  • Після перезавантаження за допомогою програмиPciExpressможна робити запис/читання регістрів.

ядро

Кастомізація модуля lbus_registers.v

Покажемо, як здійснити ці дії практично. • Визначаємо ім'я регістру та його довжину:

• Визначаємо строби запису та читання для цього регістру:

• Пишемо always-блок для цього регістру. Це зручно робити за допомогою оператораgenerate. У найпростішому випадку код виглядає так:

• До блоку always_comb

додаємо нову гілочку всередині оператора case:

Вищеописані дії повторюємо длякожного користувача регістру.

Інтерфейс модуля

Інтерфейс модуля визначено так:

Налаштування параметрів

Хардкорна конфа за С++. Ми запрошуємо лише профі.