Блог
[один тактовый тракт на одной плате AX7203; светодиоды читались глазом, считывания счётчика нет; сборка nextpnr-xilinx на 115 коммитов позади main, с одним влитым исправлением, применённым локально; быстрый цикл засекался на одном маленьком дизайне] Выход MMCM может дойти до регионального тактового буфера через тракт performance clock, и две строки в базе Project X-Ray говорят, какие биты этот тракт включают. Со строками master prjxray-db счётчик, тактируемый через него, на XC7A200T не идёт. Со строками, которые мы предложили в openXC7/prjxray-db#30, идёт, а два битстрима различаются ровно в трёх битах. Сброс любого одного из трёх снова останавливает счётчик, так что нужен каждый. main nextpnr-xilinx всё ещё фиксирует базу со старыми строками. Попутно цикл от правки до платы сократился с примерно 104–111 с до примерно 19–28 с, в основном за счёт флага роутера, ассемблера из t27-спеков и более быстрого такта JTAG.
MMCM в тайле управления тактами Xilinx 7-series может отдать выход региональным тактовым буферам через тракт performance clock. Тракт состоит из двух мультиплексоров: один в тайле CMT (CLK_PERF0–CLK_PERF3), второй в тайле HCLK_CMT над ним (PERFCLK0–PERFCLK3). В базе Project X-Ray есть строки, которые говорят, какие конфигурационные биты выбирают каждый вход. Для тракта из этого поста строки на master prjxray-db короткие. CLK_PERF2.CLKOUT3 — это один 29_994, а PERFCLK2.MUXED2 — 28_176 29_133. Строки, которые мы предложили в openXC7/prjxray-db#30 на коммите c030ed6, добавляют 28_994 и 29_1022 к первой и 28_180 ко второй.
Эти строки выведены из популяции. cavearr провёл кампанию из 1083 образцов Vivado, и прежде чем писать строки, мы заново получили его числа своим считывателем битов. Популяция говорит, какие биты меняются вместе, но не говорит, что дизайн работает. Этот пост — половина с платой.
Плата — ALINX AX7203 (xc7a200tfbg484-2). Тактовый сигнал платы 200 МГц идёт через IBUFDS и BUFG в MMCM. VCO работает на 1000 МГц, CLKOUT3_DIVIDE = 10, так что CLKOUT3 — 100 МГц. CLKOUT3 идёт через CLK_PERF2 и PERFCLK2 <- MUXED2 в BUFR в режиме bypass, а BUFR тактирует 27-битный счётчик. Опорный сигнал — 28-битный счётчик на BUFG. Старший бит каждого счётчика зажигает светодиод, так что оба должны переключаться каждые 1,34 с: 2^27 / 100 МГц = 2^28 / 200 МГц. Третий светодиод часто мигает, пока MMCM выдаёт LOCKED.
Счётчик стоит в обычной логике, а не в столбце ввода-вывода, поэтому такт должен выйти из BUFR через горизонтальный тактовый хребет. Тот же приём использовался для однобитного A/B в одном из прошлых постов, и этот пробник тоже зависит от бита ENABLE_BUFFER, который тот пост проверил.
Один прогон размещения и разводки дал один FASM-файл, и fasm2frames собрал его дважды. Первый раз против master prjxray-db 517d66a, второй — против того же checkout с восемью файлами c030ed6, скопированными поверх. После sync word два битстрима различаются ровно в трёх битах, и все три относятся к PERF: 28_994 и 29_1022 в тайле CMT и 28_180 в тайле HCLK_CMT.
| строки | опорный светодиод | светодиод счётчика BUFR | LOCKED |
|---|---|---|---|
master 517d66a | мигает, ~1,3 с | не меняется | есть |
c030ed6 | мигает, ~1,3 с | мигает в такт с опорным | есть |
Светодиоды на этой плате активны низким уровнем, так что «не меняется» значит, что счётчик застыл в начальном значении. Со строками master MMCM захватывает частоту и опорный счётчик идёт, но до BUFR такт не доходит.
Со всеми тремя битами счётчик идёт, но это не показывает, что нужен каждый: один может оказаться попутчиком. Поэтому мы взяли рабочие кадры, сбросили ровно один из трёх битов и для каждого случая записали битстрим, без новой разводки. После sync word каждый нокаут отличается от рабочего битстрима в трёх байтах: сам бит и ECC-слово кадра.
| сброшенный бит | чья это строка | светодиод счётчика BUFR |
|---|---|---|
никакой (строки c030ed6) | мигает в такт с опорным | |
28_994 | CLK_PERF2.CLKOUT3 | не меняется |
29_1022 | CLK_PERF2.CLKOUT3 | не меняется |
28_180 | PERFCLK2.MUXED2 (бит used) | не меняется |
| никакой, повторная прошивка после нокаутов | мигает в такт с опорным |
Сброс любого одного бита останавливает счётчик, а рабочий битстрим, прошитый повторно после нокаутов, снова работает, так что состояние платы между прошивками не менялось. 28_180 — бит, который наша собственная ранняя версия строк пропустила. Это бит «used» тайла HCLK, (26+p)_180 для PERFCLKp. Мы заметили, что его нет, только когда проверка начала считать каждый бит из фиксированного набора, а не только биты, которые упоминает какая-нибудь строка.
perf2.py diff · knockout · the three CLK_PERF2 bits
perf2.py diff называет три бита, которыми различаются два битстрима A/B, и ни одна строка master не использует ни одного из них. perf2.py knockout заново собирает три файла кадров для нокаутов, каждый байт в байт равен прошитому, и каждый .bit нокаута отличается от рабочего в 3 байтах после sync word. Светодиодов в записи нет. Каждый напечатанный байт настоящий; приглашение и набор команд постановочные, паузы длиннее 2 с сокращены. Сама запись на английском. Открыть запись на отдельной странице.Базу читают в двух направлениях: fasm2frames кодирует фичи в биты, а bit2fasm декодирует биты обратно в фичи. Мы декодировали оба битстрима обеими базами и оставили PERF-фичи двух тайлов.
| битстрим | декодирован с master | декодирован с c030ed6 |
|---|---|---|
| строки master (счётчик стоит) | CLK_PERF2.CLKOUT3, PERFCLK2.MUXED2 | ничего |
строки c030ed6 (счётчик идёт) | CLK_PERF2.CLKOUT3, PERFCLK2.MUXED2 | CLK_PERF2.CLKOUT3, PERFCLK2.MUXED2 |
Со строками master мёртвый битстрим декодируется так, будто тракт настроен. Каждая строка master — подмножество настоящей, и все её биты на месте. Поэтому декодер на этих строках сообщает о рабочем тактовом тракте, которого в кремнии нет. С c030ed6 декодирование совпадает с платой в обоих случаях.
prjxray-db#30 открыт. main nextpnr-xilinx фиксирует prjxray-db на 6b8695e — это prjxray-db#13 от cavearr, влитый 7 сентября. На этом коммите CLK_PERF2.CLKOUT3 — это 29_994, а PERFCLK2.MUXED2 — 28_176 29_133: те же строки, что на master 517d66a, с которыми счётчик здесь стоял. Мы прочитали строки на этом коммите. Сам main nextpnr-xilinx мы не собирали и пробник через него не прогоняли.
Этот тракт выбрал не роутер. Если ничего не делать, nextpnr ведёт CLKOUT3 через CLK_PERF0, для которого на master строк нет вообще. Чёрный список pip убрал альтернативы, так что разводке пришлось пройти через CLK_PERF2 <- CLKOUT3 и PERFCLK2 <- MUXED2.
Размещали и разводили классическим nextpnr-xilinx. Локальная chip database himbaechel для xc7a200t была сгенерирована из базы без PERF-строк, поэтому у этих pip не было конфигурационных битов, и они выпадали.
Классический бинарник был устаревшим: собран из b608fd2c, на 115 коммитов позади main openXC7/nextpnr-xilinx. Мы узнали это только после первых прогонов на плате, по двум симптомам:
MMCME2_BASE он не захватывал частоту, потому что в FASM не было ZINV_RST и ZINV_PWRDWN. AssassinK786 исправил это в nextpnr-xilinx#191, влитом 9 сентября. Мы поставили вместо него MMCME2_ADV, который пишет оба бита.00_31, не записывалось. Это наш собственный nextpnr-xilinx#205, влитый 24 сентября, которого в этой сборке не было. Мы применили его локально. Разводка не изменилась, в FASM добавились три строки, и они есть в обоих битстримах A/B.Урок, который мы записали: прежде чем винить инструмент, проверить git log HEAD..origin/main. Ранний черновик этого отчёта утверждал, что классический nextpnr-xilinx так и не получил исправление, которое он на самом деле получил, и исправление было нашим.
Каждый нокаут требует прошивки и взгляда на светодиоды, так что время от правки до платы важно. В начале один цикл занимал около 104–111 с. К концу — около 19–28 с. Синтеза в таблице нет: здесь его не засекали.
| шаг | до | после | что изменилось |
|---|---|---|---|
| размещение и разводка | 49 с | 13,2 с | --router router1 вместо router2 |
| FASM в кадры | 37–39 с | 0,43–1,72 с | bitwalk, ассемблер из t27-спеков, вместо fasm2frames |
| кадры в битстрим | 0,8 с | 0,8 с | без изменений (xc7frames2bit) |
| прошивка в SRAM | 17,5–22,6 с | 4,5–12,2 с | openFPGALoader --freq 30000000 |
| итого | ~104–111 с | ~19–28 с |
По логу router2 потратил 38,1 с, но времена по отдельным цепям, которые он сообщает, в сумме дают около 1,5 с, так что большая часть времени ушла не на разводку цепей. Router1 закончил разводку за 2,53 с. Две разводки различаются на 225 строк FASM, но идут через один и тот же PERF-тракт. Битстрим от router1 мы прошили, и два светодиода мигают вместе. Обе разводки показывают максимальную частоту выше 270 МГц на обоих тактах при целевых 12 МГц по умолчанию, так что тайминг ни разу не был под давлением.
bitwalk записал кадры, байт в байт совпадающие с fasm2frames, для обеих баз. Нокауты вовсе обходились без разводки: правка кадров, кадры в битстрим, прошивка — около 6–14 с. На 30 МГц прошивка занимала от 4,5 до 12,2 с для битстримов одного размера, и мы не знаем почему.
После работы с платой записан ещё один цикл. Размещение и разводка в нём заняли 5,95 с, а не 13,2 с, а шаг из кадров в битстрим — 2,11 с, а не 0,8 с. Другие задачи всё это время держали ноутбук на load average около 110, так что отдельный замер здесь гуляет на столько, и ни одно из чисел не точнее другого.
perf2.py loop --flash · place and route to SRAM, timed
perf2.py loop --flash размещает и разводит пробник через router1, собирает его bitwalk и xc7frames2bit, проверяет, что результат после sync word совпадает с битстримом, который работал на плате, и загружает его в SRAM. В этой записи: размещение и разводка 5,95 с (из них router1 сообщает 0,78 с), FASM в кадры 1,14 с, кадры в битстрим 2,11 с, загрузка в SRAM 9,85 с, всего 19,06 с, при этом другие задачи держали ноутбук на load average около 110 на 8 ядрах. Синтеза в ней нет. Каждый напечатанный байт настоящий; приглашение и набор команд постановочные, паузы длиннее 2 с сокращены. Сама запись на английском. Открыть запись на отдельной странице.Прошлый пост говорил, что ничто в нём не указывает путь к более быстрой разводке. Это тоже не он, в том смысле, который имел в виду тот пост: это флаг роутера, измеренный на дизайне из нескольких сотен проводов. Выдержит ли router1 дизайн из того поста на 121 587 строк, где размещение и разводка занимают 70,1 с, мы не измеряли.
CLK_PERF, другие выходы MMCM, другие PERFCLK, левая сторона кристалла, другие кристаллы и семейства.Поработаем вместе
Я аудирую RTL и строю независимые побитово точные модели, затем провожу результат через синтез и, когда это полезно, проверяю на плате Artix-7. Первый модуль проверки — бесплатно.