- docs/stand.md: состав стенда, схема и таблица соединений, питание, порядок работы, нормальные показания на ПК и на выходе ЦАП, неисправности; - README: UART через мост BL616 вместо внешнего FT232, быстрый старт, структура, команды симуляции через --elab-run (работают и с mcode-сборкой GHDL), python вместо py -3, список локальной документации; - .gitignore: мусор генератора IP Gowin, Python, Windows.
15 KiB
Стенд цифрового микрофона
Стенд проверяет цифровой микрофон SPH9855LM4H-C, вынесенный на кабель с линией LVDS, вместе с трактом его обработки в ПЛИС. ПЛИС тактирует микрофон, принимает поток PDM, приводит его к 24 бит / 12 500 Гц и отдаёт отсчёты сразу в две стороны:
- на ПК по USB — кадры с CRC: запись, живой просмотр, прослушивание;
- на ЦАП PCM5102A — аналоговый сигнал, который смотрят осциллографом.
Обе ветви получают одни и те же отсчёты. Кнопкой на плате поднимается усиление только ветви ЦАП, на ПК всегда уходит исходная шкала.
Состав
| Узел | Что это | Роль на стенде |
|---|---|---|
| Плата микрофона | SPH9855LM4H-C и приёмопередатчики SN65LVDS | PDM-микрофон; вывод SELECT задан на плате |
| Кабель | две пары LVDS: CLK к микрофону, DATA от микрофона | SN65LVDS на обоих концах |
| Tang Primer 25K + Dock | модуль GW5A-LV25MG121NC1/I0, ревизия A | тактирование микрофона, дециматор, кадры UART, I2S |
| Мост BL616 на Dock | встроенный отладчик с заменённой прошивкой (отдельный проект BL616): DirtyJTAG + CDC-UART | загрузка битстрима и UART на ПК по одному USB-C |
| Модуль ЦАП | PCM5102A на своей плате, питание через LDO TPS7A2033 | I2S -> аналог, выход OUTL на BNC |
| Осциллограф | — | смотрит выход ЦАП |
| ПК | Windows, Python 3.10+, openFPGALoader | сборка, загрузка, запись, просмотр, прослушивание |
Схема
Плата микрофона Tang Primer 25K + Dock (GW5A-25A)
+----------------------+ кабель LVDS +--------------------------------------+
| SPH9855LM4H-C | | |
| CLK <-- SN65LVDS <====== пара CLK ======< SN65LVDS <-- K8 MIC_CLK 3.125 МГц |
| DATA --> SN65LVDS >====== пара DATA =====> SN65LVDS --> K9 MIC_DAT PDM |
| SELECT: на плате | | |
+----------------------+ | E2 генератор 50 МГц |
| PDM -> CIC -> ФНЧ -> 12 500 Гц |
+----------------------+ I2S | |
| Модуль ЦАП PCM5102A |<--------------------+ G1 SCK G2 BCK L4 LRCK L3 DIN |
| OUTL -> BNC ------+--> осциллограф | |
+----------------------+ | C3 UART_TX --> BL616 --+ |
| JTAG <--------- BL616 <-+--> USB-C --> ПК
| | COM14 + DirtyJTAG
| H11 кнопка S1: усиление ЦАП |
| E8 светодиод: состояние, усиление |
| E3 отладка: выход PLL 80 МГц |
+--------------------------------------+
Земля у ПЛИС, линии LVDS и модуля ЦАП общая.
Соединения
| Цепь | Вывод ПЛИС | Банк | Где на плате | Куда идёт |
|---|---|---|---|---|
| clk | E2 | 5 | генератор 50 МГц | системный клок; весь тракт и I2S делятся от него, без PLL |
| MIC_CLK | K8 | 0 | гребёнка J3 | вход драйвера SN65LVDS, пара CLK к микрофону, 3.125 МГц |
| MIC_DAT | K9 | 0 | гребёнка J3 | выход приёмника SN65LVDS, пара DATA от микрофона; подтяжка ПЛИС вниз |
| DAC_SCK | G1 | 2 | гребёнка J3 | SCK модуля ЦАП, 12.5 МГц = 256 fS |
| I2S_BCK | G2 | 2 | гребёнка J3 | BCK модуля ЦАП, 3.125 МГц = 64 fS |
| I2S_LRCK | L4 | 2 | гребёнка J3 | LRCK модуля ЦАП, fS = 48 828 Гц |
| I2S_DIN | L3 | 2 | гребёнка J3 | DIN модуля ЦАП |
| UART_TX | C3 | 4 | цепь FPGA_UART_TX Dock |
RX моста BL616 -> COM-порт на ПК, 921600 8N1 |
| BTN_GAIN | H11 | 7 | кнопка S1 Dock | замыкает вывод на +3.3 В через 100 Ом; подтяжка ПЛИС вниз |
| LED | E8 | 4 | светодиод (READY) | индикация, см. ниже |
| clk_80MHz | E3 | 4 | гребёнка J3 | только отладка: выход PLL, к тракту не относится |
Привязка выводов — в src/DigMic.cst. Номера контактов
гребёнки J3 — по схеме Dock (Tang_25K_60033.pdf, цепи вида K8_IOT56B_40P).
Направления MIC_CLK и MIC_DAT проверены на плате до первой прошивки диагностической прошивкой, которая ничего не выдаёт на спорные выводы: K8 висит на подтяжке ПЛИС (вход драйвера), K9 держит приёмник.
Питание
- Dock — от USB-C; тот же разъём даёт JTAG и UART через BL616.
- VCCIO банков 6/7 на этой плате подаётся снаружи, через контакты 29 и 31 гребёнки. Без 3.3 В на них не работает кнопка S1 (H11, банк 7).
- Модуль ЦАП — на разъём X1 (цепь
+5.5V), дальше два LDO TPS7A2033 раздельно дают аналоговые и цифровые 3.3 В. На BNC выведен только OUTL; ПЛИС шлёт один и тот же отсчёт в оба канала. - Сторона микрофона — по схеме платы микрофона; сам микрофон допускает 1.65...3.6 В.
ПО на ПК
| Что | Зачем |
|---|---|
| Gowin EDA V1.9.12 | сборка в IDE |
openFPGALoader ≥ 1.1.0 или TangProgrammer.exe — оба лежат в проекте BL616 |
загрузка битстрима через DirtyJTAG |
Python 3.10+ и пакеты из tools/requirements.txt |
запись, просмотр, прослушивание |
| GHDL, Icarus Verilog | только симуляция |
Gowin Programmer с заменённой прошивкой BL616 не работает: он видит
только мост со штатной прошивкой Sipeed. Вернуть штатную —
flash.ps1 -Restore в проекте BL616, но со штатной UART BL616 работает хуже.
python -m pip install -r tools/requirements.txt
Порядок работы
1. Собрать
Gowin IDE: открыть DigMic.gprj, Run All.
Битстрим — impl\pnr\DigMic.fs. Проект собирается под Device Version A
(gw5a25a-002). Это важно: битстрим под B на этой плате не выдаёт ни
байта, а программатор расхождения не замечает, JTAG-код у ревизий одинаковый.
2. Загрузить
openFPGALoader -c dirtyJtag impl\pnr\DigMic.fs
Битстрим живёт в SRAM до выключения питания. Чтобы ПЛИС стартовала с ним
сама, его записывают во флеш: openFPGALoader -c dirtyJtag -f impl\pnr\DigMic.fs.
То же самое умеет TangProgrammer.exe, а с флажком «Загружать в SRAM
автоматически» он заливает каждую новую сборку из IDE.
3. Проверить по светодиоду
| Светодиод | Что значит |
|---|---|
| не мигает, горит или погашен | клока нет или битстрим не загружен |
| медленно, 2 Гц | клок есть, отсчёты с дециматора не приходят |
| быстро, 10 Гц | отсчёты идут: тракт PDM -> CIC -> ФНЧ работает |
| пауза, N коротких вспышек, пауза | только что нажали S1: выбрана ступень N |
| пауза, одна длинная вспышка 1 с, пауза | только что нажали S1: ступень 0 |
Рабочее состояние — быстрое мигание.
4. Посмотреть поток на ПК
python tools/uart_live.py --port COM14
COM14 — порт моста BL616 на этом ПК; на другом номер другой, его
показывает python tools/uart_capture.py --list. Порт держит только одна
программа: uart_live, uart_capture и uart_audio по очереди.
В строке состояния исправный стенд показывает:
| Показатель | Норма |
|---|---|
| кадров/с | 250 |
| CRC, потеряно, ресинхр | 0; одна-две ошибки CRC и ресинхронизации в первый момент — норма: порт открылся посреди кадра |
| STATUS | чисто (FIFO=1 — переполнение буфера, SAT=1 — выход упёрся в шкалу) |
| тишина в комнате | СКО около −72 dBFS |
| смещение нуля | около −90 dBFS |
| речь рядом с микрофоном | пики около −50 dBFS |
5. Посмотреть выход ЦАП
Осциллограф — на BNC модуля ЦАП. Полная шкала 24 бит — 2.1 В скз на выходе PCM5102A. При ступени 0 сигнал там в той же шкале, что на ПК, то есть доли и единицы милливольт. Каждое нажатие S1 даёт ровно +6.02 дБ (сдвиг на разряд), после ступени 8 снова 0:
| Ступень S1 | Усиление | Фон комнаты, −72 dBFS | Речь, −50 dBFS |
|---|---|---|---|
| 0 | 0 дБ | ≈ 0.5 мВ скз | ≈ 7 мВ |
| 4 | +24 дБ | ≈ 8 мВ | ≈ 0.1 В |
| 8 | +48 дБ | ≈ 0.13 В | ≈ 1.7 В, у предела шкалы |
На ступени 8 всё громче примерно 85 дБ SPL упирается в шкалу и ограничивается; признака этого нигде нет, на ПК при этом шкала прежняя. Полоса выхода, как у всего тракта, — до 5 кГц, задержка относительно UART — один отсчёт, 80 мкс.
6. Записать и послушать
python tools/uart_capture.py --port COM14 --seconds 10 --out test1
python tools/Bin_to_wav.py test1.bin
python tools/uart_audio.py --port COM14
uart_capture пишет test1.raw (поток как есть), test1.bin (только
отсчёты, 3 байта BE) и test1.log со сводкой: те же показатели, что в
таблице п. 4. Bin_to_wav делает из .bin WAV. uart_audio отправляет
поток на звуковую карту ПК, слушать лучше в наушниках. Подробности — в
README.
Если не работает
| Признак | Вероятная причина | Что сделать |
|---|---|---|
| светодиод не мигает | битстрим не загружен или нет клока | загрузить заново; с LED_SRC = 3 в Top.vhd светодиод мигает ровно 1 Гц прямо от clk: другой период значит, что клок не 50 МГц |
| светодиод мигает медленно | отсчёты не идут: обрыв MIC_CLK или MIC_DAT, нет питания линии или микрофона | осциллографом: 3.125 МГц на K8 и PDM на K9; LED_SRC = 2 — мигание от битов PDM, 1 — от CIC: быстрое мерцание значит, что этот участок живой |
| на ПК ни одного байта | битстрим собран под ревизию B; открыт не тот порт; UART не на C3 | проверить Device Version A в проекте; uart_capture.py --list; UART_TX в DigMic.cst |
| CRC или ресинхронизации растут постоянно | скорость порта не 921600 | --baud 921600, это значение по умолчанию |
кадров/с меньше 250, потеряно растёт |
байты теряются в мосте или драйвере, либо разбор не успевает | uart_capture.py --port COM14 --dump: только приём без разбора, сравнивает скорость с ожидаемой и говорит, где потери |
| сигнал пропал или стал шумом после замены кабеля или SN65LVDS | сдвинулась точка выборки бита | перемерить фазу смены MIC_DAT относительно MIC_CLK и поправить MIC_SMP_CNT в Top.vhd, см. README |
| кнопка S1 не меняет ступень | нет 3.3 В на VCCIO банков 6/7 | подать 3.3 В на контакты 29 и 31 гребёнки |
| на ПК сигнал есть, на осциллографе нет | ступень 0: на выходе доли мВ; нет питания модуля ЦАП | нажать S1 несколько раз; проверить питание X1 и общую землю |
could not open port |
порт держит другая программа | закрыть uart_live / uart_audio / терминал |
| Gowin Programmer не видит кабель | на BL616 заменённая прошивка | грузить через openFPGALoader или TangProgrammer |
Чего не делать
Два ограничения кристалла найдены на железе ещё при сборке под ревизию B. Под A их пока не перепроверяли, поэтому они остаются в силе:
- не расширять аккумуляторы CIC сверх 18 бит: при 20 битах и больше тракт молча отдаёт нули, хотя синтез, тайминг и симуляция чистые;
- не добавлять сброс по включению: счётчик, держащий
rst_n, убивает тракт.
Подробности — в README, раздел про ограничения кристалла.