半導体設計民主化のための自作RISC-V SoC実践編

PicoRV32 と Wishbone で作る、フィジカルAI時代の実用オリジナルチップ

← 講義ポータルに戻る 実験並走記録 本章のRTLは骨格・未検証

第8章 音声サブシステム ― 先輩が弱かった「耳と口」を主役にする

ここから本ボードの差別化の主役に入ります。先輩ボード(Arduino UNO・CH32V003・ESP32-C 系)が、どれも音声に弱かったのは偶然ではありません。マイコンに少数の固定ペリフェラルしか持てない構造では、音声のような連続・並列・リアルタイムな信号を捌くのが苦手だからです。私たちのSoCは、ここでこそFPGAの本領を発揮します。本章では、耳(マイク入力)→処理(FPGA)→口(スピーカ出力)という音声の流れを、設計判断とともに組み立てます。

本章の留保(毎章の約束)。 掲載するRTLは骨格・未検証です。完全な動くコードと、構文/import/シミュレーション/FPGA実機の検証は、設計合意のうえ専用ビルド工程に一括して回します。音声サブシステムは現状の専用ビルド工程(最小SoC→外部接続結合まで)のにあたるため、本章は設計と判断軸を固めることに重きを置きます。外部の製品名・スペック・入手性は変動するため、本文では断定せず、一次情報(各メーカーのデータシート)での確認をお願いします。

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 入力の選択肢 ― マイクをどう取り込むか

耳(入力)側は、品質と手間のトレードオフでいくつかの道があります。いずれも断定せず、用途に合わせて選ぶ設計判断です。

誇張はしません。 入力の具体(マイクの型・サンプルレート・分解能・必要なアンチエイリアス)は、選ぶ部品で変わります。本講座は「どの道があり、何がトレードオフか」を示し、特定の構成を断定しません。実装時に現物のデータシートで確定します([改訂マーカー:使用マイク・入力経路])。

8.8 FPGAの強みを活かす ― マイク→処理、そして"頭脳はネット越し"

音が取り込めたら、FPGAの並列・DSPの出番です。たとえばFIRフィルタでノイズを削る、ゲイン調整する、FFTで周波数成分を見る――こうした前処理は、CPUを使わずFPGAのハードで流せます。ここが先輩マイコンに対する明確な差別化です。

旗印どおり、役割を分けます。 ただし本講座は「ボード単体で音声認識(ASR)や音声合成(TTS)を回す」とは約束しません。重い認識・生成はネット越しのAI(API)に委ねる、というのが旗印「ボード=身体、頭脳=ネット越し」です。本ボードの役割は、耳で取り(前処理して)、通信で送り(第5〜6章)、返ってきた応答を口で鳴らすこと。音声サブシステムは、その身体側の耳と口を担います。
発展:どこまでを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実機の順で、欲張らず段階的に確かめます。

  1. 出力(シミュ→FPGA)。 シグマデルタに既知のサンプル列(正弦波テーブル等)を流し、波形の密度が正しく変わることをシミュで確認 → ピン+RC+アンプで実際にトーンを鳴らす。
  2. 入出力スルー(FPGA)。 ルートA採用時:I2Sコーデックの入力を受け、そのまま出力へ流す「パススルー」で、耳と口がつながることを確認。
  3. 前処理(FPGA)。 入力にFIRやゲインを1段かけ、効果が音として分かることを確認。重い認識はここでは載せない(旗印どおりネット越しへ)。
[改訂マーカー] 本章で実機実測して確定する値:サンプルレートとタイマ分周、シグマデルタのRCフィルタ定数・アンプ、(ルートA時)使用コーデックの現物(ピン配置・I2Sモード・MCLK要否・分解能)、入力経路(I2S/PDM/XADC)の選択、追加後のFPGA利用率(DSPスライス含む)。完全な動くRTLと検証は、設計合意済みの専用ビルド工程でまとめて実施します。

8.11 この章のまとめ

身体に「耳」と「口」が付きました。次章は、フィジカルAIの足回りです。端子から大電流は流せないという現実を踏まえ、外部モータードライバICと組み合わせて、DCモータ・ステッピング・サーボを動かします――第9章:モータードライブ。ボードに「動く身体」を与える章です。