お知らせ:この記事はJLCPCBの提供でお送りしています。

またまた間が空いてしまいましたが、第1回第4回と連載してきたESP32+FPGAオーディオ基板の解説記事です。今回は、基板上のFPGAに実装している処理ブロックのうち、演算パイプライン外の処理ブロックについて説明します。

FPGA内部の構成

まずは第4回で示した今回の基板のFPGAの内部構成を再掲します。今回はここに示した処理ブロックのうち、SPIスレーブ、コマンドデコーダ、I2Sマスタ1について順に解説していきます。

演算パイプライン外の処理ブロック

SPIスレーブ

最初に取り上げるのはMCUであるESP32からのコマンドを受け取るSPIスレーブです。今回は接続先がESP32と決まっていますし、ESP32側のプログラムも自分で書くので、できるだけ手抜きをしてMode 02だけをサポートするSPIスレーブを書きました。

SPIスレーブのブロック図を上に示します。SPIスレーブは外部からのSCLK(クロック)に合わせてデータをやり取りする必要があるため、どこかでSCLKを含めた外部の信号をFPGA内のクロックに同期させる必要があります。今回はここも手を抜いてフリップフロップ(FF)を2段重ねることでSPIバスの各信号を同期化しています。SPIバスの通信速度を追求したい場合はSPIスレーブ全体をSCLK基準で動かし、シフトレジスタの出力のところでFPGA内部のクロックに同期化する構成が取られると思いますが、今回はFF2段重ねでの同期化でも実力値として10MHz程度で通信できているので、FF2段重ねで済ませています。

また、今回の実装ではESP32からSPI Flashに書き込みを行うときのために、ESP32から入ってくるSPIバスの信号をパススルーしてSPI Flashに送るモードも用意しています。この機能を実現するために、入力の部分にマルチプレクサが入っています。FPGAのあるピンがHかLかを見て、MCUからのSPIバスの信号をこのSPIスレーブに接続するか、SPI Flashにパススルーするかを切り替えています。また、パススルーモードでないときには、SPI FlashにはSPI Flashコントローラからの信号が接続されるようになっています。

コマンドデコーダ

次はコマンドデコーダです。コマンドデコーダはSPIスレーブが受け取ったデータを解釈して、他の処理ブロックに対して設定値を書き込む機能を担当しています。

まず、コマンドデコーダはSPIスレーブから受け取った先頭の1バイト(SPIバスのCS信号がアクティブになってから最初の1バイト)の数値を見てコマンド種別を判断します。次に受け取った1バイトはアドレス、その後に続く最大4バイトを設定値として解釈します。コマンド種別情報は、パイプライン内のどの処理ブロックにデータを送り込むかを示す信号の生成に使われます。また、アドレス部の情報と合わせて、各処理ブロックの設定レジスタ群のどこに設定値を書き込むかを決定するのにも使われます。

コマンドデコーダが解釈するコマンド体系はあらかじめExcelで表にまとめて設計し、その表を見ながらSystemVerilogで実装しています。コマンド体系の本格的な最適化はしていませんが、コマンド種別を示す先頭の1バイトの割り当ては似た機能のものごとに8個または16個のグループとして割り当てるという配慮を一応しています。こうすることで各処理ブロックへの書き込み制御信号を生成する際に入力として使う信号の数が多少減るはずですが、どこまで回路規模に効いているかは未確認です。

I2Sマスタ

演算パイプライン外の処理ブロックの最後はI2Sマスタ3です。I2SはInter-IC Soundの略で、その名前の通り、ADCやDACなどのIC間でデジタルオーディオ信号をやり取りするためのバス規格です。I2Sマスタは、演算パイプラインで生成されたオーディオデータを、I2Sバスを介して基板上に実装されたオーディオDACであるPCM5100Aに送り込む機能を担っています。

上にI2Sバスの通信波形の概略図を示します。I2Sバスでは同期用の基準クロックとなるSCK、左右どちらのチャンネルのデータを送信しているのかを区別するためのWS、そして実際の音声データであるSDの3つの信号を送受信します。

上の図では簡略化のため、オーディオ信号の1サンプルを8bitとして表記していますが、一般的には1サンプルは16bit,24bit,32bitのいずれかで表現されます。左右の2チャンネルのデータを1本のSD信号線で送るため、SCKはサンプリング周波数の32(16bit × 2)~64(32bit × 2)倍の周波数となります。

次にI2Sマスタのブロック図を示します。基本的にはPLLから供給される49.152MHzのクロックを分周して出力しつつ、シフトレジスタを駆動する回路となります。また、SystemVerilogのソースはパラメータを変更することで1サンプルあたりのbit数を変えることができるように記述していますが、今回は1サンプルあたり32bitのデータを送る仕様としています。

PLLからの49.152MHzのクロックは、まずSCKを生成するためのクロックディバイダに入ります。モダンなADC/DAC では、オーバーサンプリングなどのチップ内部の処理のために、SCK,WS,SDの他に、SCKの数倍の周波数のクロックをMCLK(Master Clock)として要求する場合もあります。今回の基板で使用しているDACであるPCM5100AもMCLKを必要とするDACの一つです。ただし、PCM5100AはMCLKが入力されない場合、SCKから内蔵のPLLを使ってMCLKを自動で生成する機能を持っているため、MCLKを外部から供給しなくても動かすことができます。今回はFPGAを使っているためMCLKを簡単に生成できることと、不要なPLLが間に挟まることによって性能が多少落ちること4を避けたいという理由から、MCLKもFPGA側で生成しDACへ供給しています。そのため、クロックディバイダでは49.152MHzを1/4分周したMCLKと、1/16分周したSCKを生成しています。

WS信号はSCKをさらに分周して生成しています。WS信号は送信中のデータが右チャンネルか左チャンネルかを区別する信号であるとともに、送り出すデータの頭のタイミング(WSが変化してからSCKが1クロック経過した後に送り出すデータがデータの最上位Bitとなる)を規定するクロックです。そのため、WS信号をトリガとして、あらかじめバッファレジスタにバッファしておいたオーディオデータをシフトレジスタにロードする処理も行っています。

次回予告

今回はESP32+FPGAオーディオ基板のFPGA側の処理ブロックのうち、演算パイプライン外の要素について紹介しました。次回は最終回として、演算パイプラインの中の処理ブロックについて紹介する予定です。お楽しみに!

  1. PLLについては第4回でどのように使っているか簡単に説明しています。
  2. クロックの立ち上がりでサンプル、立下りでシフト、初期状態でクロックはLow
  3. 2022年2月に改訂されたI2S規格資料に従うと、I2Sコントローラ、という呼び方が正しそうです(以前のスレーブはターゲットと呼ばれるようです)。が、本記事では広く知られているマスタ・スレーブ表記を採用します。
  4. 聞き分けられるかは別としてPCM5100AのようなΔΣ方式のDACでは、クロックの安定度が落ちると特性が悪化します。
公開日:2022/08/26