Files
digital_microphone/docs/stand.md
T
Gromov_IA 525a1dd90e Описание стенда и быстрый старт
- docs/stand.md: состав стенда, схема и таблица соединений, питание,
  порядок работы, нормальные показания на ПК и на выходе ЦАП, неисправности;
- README: UART через мост BL616 вместо внешнего FT232, быстрый старт,
  структура, команды симуляции через --elab-run (работают и с mcode-сборкой
  GHDL), python вместо py -3, список локальной документации;
- .gitignore: мусор генератора IP Gowin, Python, Windows.
2026-10-02 14:21:07 +03:00

212 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Стенд цифрового микрофона
Стенд проверяет цифровой микрофон 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`](../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`](../tools/requirements.txt) | запись, просмотр, прослушивание |
| GHDL, Icarus Verilog | только симуляция |
Gowin Programmer с заменённой прошивкой BL616 **не работает**: он видит
только мост со штатной прошивкой Sipeed. Вернуть штатную —
`flash.ps1 -Restore` в проекте BL616, но со штатной UART BL616 работает хуже.
```bash
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. Загрузить
```powershell
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. Посмотреть поток на ПК
```bash
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. Записать и послушать
```bash
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](../README.md#по-на-пк).
## Если не работает
| Признак | Вероятная причина | Что сделать |
|:--|:--|:--|
| светодиод не мигает | битстрим не загружен или нет клока | загрузить заново; с `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, раздел про ограничения кристалла.