第8章 音声サブシステム ― 先輩が弱かった「耳と口」を主役にする
ここから本ボードの差別化の主役に入ります。先輩ボード(Arduino UNO・CH32V003・ESP32-C 系)が、どれも音声に弱かったのは偶然ではありません。マイコンに少数の固定ペリフェラルしか持てない構造では、音声のような連続・並列・リアルタイムな信号を捌くのが苦手だからです。私たちのSoCは、ここでこそFPGAの本領を発揮します。本章では、耳(マイク入力)→処理(FPGA)→口(スピーカ出力)という音声の流れを、設計判断とともに組み立てます。
8.1 なぜ音声が「差別化の主役」なのか
FPGAが音声に強い理由は、音声処理が要求するものと、FPGAの得意がそのまま噛み合うからです。
並列処理
複数チャンネル、複数のフィルタ段を同時に走らせられる。CPUの逐次実行と違い、音の流れを止めずに捌ける。
DSP(積和)
Artix-7 には乗算器(DSPスライス)があり、FIRフィルタやFFTのような積和の塊を効率よく回せる、とされる。音声の前処理に効く。
PWM/シグマデルタ
第3章で作ったPWMの発想を延ばせば、外部DACなしでも1本のピンからアナログ近似の音を出せる。出力の最短ルート。
つまり音声は「FPGAだから自然にできること」を見せる絶好の題材です。先輩の弱点を、こちらの強みで正面から上回る――それが本章の狙いです。
8.2 正直な線引き ― Basys 3 に「音声」は載っていない
最初に、誇張せず線を引きます。Basys 3 には、音声用のコーデックもオーディオ端子も載っていません(スイッチ・LED・7セグ・VGA・USB-UART・4つのPmod・XADC などが基本構成です)。ですからマイクもスピーカも、Pmod(拡張ポート)経由で外付けするか、FPGAのピンから直接アナログ近似を作ることになります。これは弱点ではなく、第4章(外部メモリ)・第6章(外部接続)と同じ、本講座の流儀――「載っていないものは外付けで、判断とともに足す」――の音声版です。
8.3 二つのルート ― 「外付けコーデック」か「ピン直接」か
音声をどう入出力するかには、性格の違う二つの道があります。どちらも一長一短で、これは設計判断です。
ルートA:外付けI2Sコーデック(高品質)
ステレオのADC/DACを載せたI2SコーデックのPmodを外付けし、FPGAはI2Sで会話する。ライン/ヘッドホン品質の入出力が狙える。配線とI2S送受信が要る。
ルートB:ピン直接(最短・低コスト)
FPGAのピンからPWM/シグマデルタで出力し、RCローパス+小型アンプ+スピーカで鳴らす。外部コーデック不要。品質は割り切る。まず音を出すのに最適。
※外付けコーデックの一例(断定回避)。 市販のI2Sオーディオ用Pmodには、ステレオのA/D・D/Aコンバータ(例として Cirrus 系のADC/DACを載せたもの、とされる)をI2Sで出すタイプがあり、Basys 3 のPmodに挿して使える、とされています。具体的な型番・分解能・サンプルレート・入手性は版や流通で変わるので、本文では断定しません。使う現物のデータシートでピン配置・I2Sのモード(マスタ/スレーブ)・MCLKの要否を必ず確認してください([改訂マーカー:使用コーデックの現物])。
※本講座の進め方(著者の判断)。 学びやすさを優先し、まずルートB(ピン直接)で「とりあえず音を出す」を達成し、FPGAの強み(PWMの延長)を直接体感します。そのうえで、品質が要る用途のためにルートA(I2Sコーデック)を設計判断として提示します。どちらを実装に進めるかは、著者の確認をいただいてから専用工程で確定します(勝手に決めません)。
8.4 I2S とは ― 三本の線で音を運ぶ
ルートAの土台になるI2S(Inter-IC Sound)は、デジタル音声を運ぶ標準的なシリアルバスです。基本は三本の線で、SPIに似た発想ですが「左右チャンネルの切り替え」を持つのが特徴です。
I2S の三本(+必要に応じ MCLK) 役割 ─────────────────────────────────────────────────────────────── BCLK(ビットクロック) 1ビットごとのタイミング WS / LRCLK(ワードセレクト)Lで左チャンネル/Hで右チャンネル(の切替) SD(シリアルデータ) 音声サンプルのビット列(送信 or 受信) ─(MCLK:マスタクロック) コーデックによっては別途要求される、とされる ─────────────────────────────────────────────────────────────── ※入力(マイク/ライン)と出力(スピーカ/ライン)で、SD が別線になる
SPI(第5章)を理解していれば、I2Sは「クロックに合わせてビット列を送受し、WSで左右を仕切る」と捉えられます。違いは、音声は止められない連続ストリームなので、CPUがバイト単位でつつくより、FPGA側に小さなFIFOを持たせて流すのが素直、という点です。
8.5 【調達/自作の判断】I2S送受信は、作るか、調達するか
ここで第3章の判断軸――「単純で・仕様が明快で・自分のメモリマップに密着しているなら自作、複雑で枯れた実績が要るなら調達」――を再適用します。I2Sの送受信そのものは、ビットを数えてWSで左右を切る比較的単純な状態機械なので、自作寄りと整理できます。一方、アナログのADC/DACは外部チップ(コーデック)に委ねます(FPGAでアナログは作れない、第6章6.7と同じ線引き)。
IP調達/自作ワークフロー:I2S 送受信
───────────────────────────────────────────────────────────────
1. 要求を言語化 ・nビット・ステレオのI2S送信/受信ができる
・Wishboneスレーブとして叩ける(FIFO+制御レジスタ)
・寛容ライセンス(自作なら不問)
2. 探索先 OpenCores/GitHub に I2S送受信のオープンRTLがある、とされる
3. 候補を絞る 「調達して読む」か「単純なので自作する」かを比較
4. 現物を確認 調達するなら、作者・ライセンス・ポート・WS極性を一次情報で確認
5. 採否を判断 本講座は教材性から「自作(骨格は専用工程で完全化)」を基本線に
6. 統合 第3章のWishboneスレーブの型でラップ(FIFO+サンプルレジスタ)
7. 検証 シミュ(既知の波形を流す)→FPGA(コーデック実機)
───────────────────────────────────────────────────────────────
※ 具体の調達IPを使う場合、固有名は現物確認を経るまで断定しない
8.6 出力の最小実装 ― シグマデルタで「とりあえず音を出す」
ルートB(ピン直接)の核は、第3章のPWMの発展形=シグマデルタです。考え方はこうです。1本のピンは0か1しか出せませんが、1と0の"密度"を音声サンプルに比例させて高速に切り替え、外付けのRCローパスフィルタで平均すれば、アナログ電圧の波形に近づきます。PWMが「デューティ比で明るさ」を作ったのと、まったく同じ発想です。
音声サンプル(nbit) → [ シグマデルタ ] → 1ピン(密度) → [ RCローパス ] → [ アンプ ] → スピーカ
(FPGA内) (外付け・受動) (外付け小型)
// sigma_dac.v ― 1bitシグマデルタDAC(PWMの発展形・骨格・未検証)
// nビット音声サンプル sample を、1本のピンの「1の密度」に変換する。
// Wishbone での書き込み(サンプル更新)は、第3章のスレーブ型でラップする。
module sigma_dac #(parameter N = 16) (
input clk,
input [N-1:0] sample, // 音声サンプル(第3章PWMの duty を多bitに拡張した発想)
output audio // 1本のピン → RCローパス → アンプ → スピーカ
);
reg [N:0] acc = 0; // 1bit余分にとり、桁上げ(acc[N])を取り出す
always @(posedge clk)
acc <= acc[N-1:0] + sample; // 桁あふれの「密度」が、そのまま出力の密度になる
assign audio = acc[N];
endmodule
※これは出力の"芯"だけ(断定回避)。 実用には、サンプルの供給速度(サンプルレート)をタイマ(第3章)で刻み、サンプル列をどこから供給するか(外部Flash/microSDの音源、あるいはCPUが生成)を決める必要があります。フィルタ定数(R・C)やアンプは外付けの受動・能動部品で、値は出したい帯域で変わるので本文では固定しません。完全な動くコードと値は専用工程/実機で詰めます([改訂マーカー:サンプルレート・フィルタ定数])。
8.7 入力の選択肢 ― マイクをどう取り込むか
耳(入力)側は、品質と手間のトレードオフでいくつかの道があります。いずれも断定せず、用途に合わせて選ぶ設計判断です。
- I2Sコーデック(ルートA): 外付けコーデックのADCから、I2Sで音声を受信。最も素直で品質も出るが、コーデックの現物確認とI2S受信が要る。
- PDMマイク: 1bitの高速パルス密度で音を出すデジタルMEMSマイク。FPGA側でデシメーション(間引きフィルタ)をかけてnビットのサンプルに戻す。配線は少ないが、フィルタ設計が要る、とされる。
- アナログ+XADC: Basys 3 には XADC(FPGA内蔵のA/D)があり、JXADC ポート経由でアナログ信号を取り込める、とされる。簡易なアナログマイク回路+XADCで、低レートの音声入力を試す道もある(音質は割り切り)。
8.8 FPGAの強みを活かす ― マイク→処理、そして"頭脳はネット越し"
音が取り込めたら、FPGAの並列・DSPの出番です。たとえばFIRフィルタでノイズを削る、ゲイン調整する、FFTで周波数成分を見る――こうした前処理は、CPUを使わずFPGAのハードで流せます。ここが先輩マイコンに対する明確な差別化です。
発展:どこまでをFPGAで、どこからをCPU/ネットに渡すか
目安は「連続・定型・低レイテンシはFPGA、判断・可変・重いはCPUかネット越しAI」です。サンプリング、フィルタ、エンベロープ検出、キーワードの単純な前処理あたりまではFPGA/CPUの守備範囲。文意の理解や自由発話の生成は、API側に委ねるのが現実的です。線をどこに引くかは用途次第で、本講座は固定の正解を置きません。
8.9 メモリマップに「音声」を足す(設計案)
音声サブシステムも、これまでと同じくWishboneスレーブとしてバスに足します。上位ニブルで住み分ける流儀のまま、新しい一席を音声に充てます(番地は実装で確定。専用ビルド工程は現状 0x8 まで=音声はその先の設計案です)。
メモリマップへの追記(設計案。番地は実装で確定)
───────────────────────────────────────────────────────────────
0x0〜0x8 既存(RAM/LED/GPIO/TIMER/PWM/Flash/UART/SPI/UART2)… M1〜M5
0x9 〜 音声(I2S送受信 + シグマデルタ出力) ← 本章で新設(予約)
例:+0 制御 / +4 ステータス(FIFO) / +8 サンプル(送) / +C サンプル(受)
───────────────────────────────────────────────────────────────
※ レジスタ構成・FIFO段数・番地は、出力(B)/コーデック(A)のどちらを採るかで変わる
8.10 【確認】この章の最小確認
音声サブシステムを、シミュ→FPGA実機の順で、欲張らず段階的に確かめます。
- 出力(シミュ→FPGA)。 シグマデルタに既知のサンプル列(正弦波テーブル等)を流し、波形の密度が正しく変わることをシミュで確認 → ピン+RC+アンプで実際にトーンを鳴らす。
- 入出力スルー(FPGA)。 ルートA採用時:I2Sコーデックの入力を受け、そのまま出力へ流す「パススルー」で、耳と口がつながることを確認。
- 前処理(FPGA)。 入力にFIRやゲインを1段かけ、効果が音として分かることを確認。重い認識はここでは載せない(旗印どおりネット越しへ)。
8.11 この章のまとめ
- 音声を差別化の主役に据えた: 並列・DSP・PWMというFPGAの強みが、音声処理の要求とそのまま噛み合う。
- 実機制約に正直に線を引いた: Basys 3 に音声は載っていない。だからPmodコーデック(ルートA)かピン直接(ルートB)で外付けする。
- I2Sを理解した: BCLK/WS/SD の三本で音を運ぶ。SPIの発想+左右切替。連続ストリームはFIFOで流す。
- 調達/自作を判断した: I2S送受信は単純で密着=自作寄り。アナログのADC/DACは外部コーデックに委ねる。
- 出力の芯を作った: シグマデルタ(PWMの発展形)で、外部DACなしに1ピンから音を出す骨格を示した(骨格・未検証)。
- 役割分担を守った: 耳と口は身体側(FPGA)、重い認識・生成は頭脳側(ネット越しAI)。誇張しない。
身体に「耳」と「口」が付きました。次章は、フィジカルAIの足回りです。端子から大電流は流せないという現実を踏まえ、外部モータードライバICと組み合わせて、DCモータ・ステッピング・サーボを動かします――第9章:モータードライブ。ボードに「動く身体」を与える章です。