LTC2380-24を使ったADC

Pocket

まずLTC2380-24とはなにか、です。これは現代の最新テクノロジーによる真のマルチビットADCです。オーディオ用としてはハイビットのマルチビットADCは完全に死滅しており、最後似有名なのはおそらくReference Recordingsが使用しているPacific Microsonics model twoでしょうか。

Lavry GoldのDACはマルチビットですが、ADCのAD122-96ですらデータシートを見る限りではDeltaSigma系に見えます。

http://www.lavryengineering.com/pdfs/lavry-ad122-96mkiii-manual.pdf

ということで現代では非常に珍しいチャレンジになりますね…と思ったら海外ではこれに真剣に取り組んでいる事例がありました。

https://www.diyaudio.com/forums/equipment-and-tools/292107-sar-adc-performance-audio-adc-project-ltc2380-24-a.html

結局、後発にはなってしまいましたが、FPGAを覚えるいい機会と捉え、FPGAを使ってLTC2380-24のデータ取得、そしてオーディオ用ADCとして使えるように、XLR入力、SPDIF出力という機能を実現してみたいと思います。

基板設計

このような感じです。見て分かる通り二層基板です。それなりのクロックを使うデジアナ混在基板かつ高額ICが乗るので本来なら4層で設計すべきなのでしょうが2層で進めてみたら比較的きれいにパターンが引けたのでこれなら大丈夫だろうと2層でスタートです。だめならあとから4層にします。

仕様としてはXLR入力左右2系統、その後2段アナログフィルタ、OPA1632で差動化してADCに入力しています。リファレンス電圧は推奨通りLTC6655-5と堅実な設計です。FPGAはCmod-A7という秋月で売っている手軽なものです。このFPGAは別プロジェクトでも使っていたのでちょうど良かったものです。

SPDIF出力はFPGAでもできるらしいですが最初からそこまでできる自信はないのでPCM9211の余剰品を使った実装になっています。I2CもFPGAでできるらしいのですが同じくこれも実績あるマイコン制御とします。余裕があればこのあたりもFPGAでできるようにチャレンジしてみたいところです。

FPGAで大きくつまづく

基板設計、部品実装、アナログ回路の性能テスト、全て問題なしです。ここまでは超順調でした。ここは自分の専門分野みたいなもので経験実績があるので全く問題ありませんでした。最大の問題はFPGAです!覚えたての頃は(まだ1ヶ月位ですが)verilogが普通のCPUの言語と違って並列処理やハイインピーダンスの概念があってなかなか難しいと思っていたのですが、本当の敵はverilogではありませんでした。

verilogを書くのは実は全然難しくありません。真に難しいのは書いたverilogがFPGAと親和性があり、ハードウェアでの実現性、ハードウェアでの制約、これらの条件をしっかりクリアしているか、このあたりが問われることです。verilogで書いたとおりに動かせるわけではないということをあとから知りました。

例えばですが次のソース、verilog的には問題がないようでそのままシンセサイズまでは通ります。でもインプリメンテーションで怒られます。

これの何が問題かと言うと、i2s_bit_countを異なるalwaysで共有しているからです。これはマルチドライブエラーで怒られます。どうやら同時に動くalways間でのレジスタの書き込みは一つだけ、あとは読み込みしか許されていないようです。このような厳しい制約があることは知りませんでしたのでとても困りました。結局次のように同じalwaysで使い回す形でなんとかしました。本当はもっと良い書き方があると思います。

(この書き方だとインプリメンテーションは通りましたが、結局内部信号の到着タイミングによって意図しないエラーになるのでやっぱりダメです!くれぐれも真似しないように)

verilogでは表現できてもFPGAでは実現できない…これが最大の難関です。試練はまだまだ続きます。

次はタイミングの問題で動作しない

上記の制約の問題はなんとかクリアしたのですが、今度はシミュレーションで動作できるのに実際にハードウェアに書き込むとデータ化けしてしまうというものです。データ化けは次のような感じです。

正常(といってもスプリアスが発生している)

データ化け、異常

これも内部タイミングの問題です。ここのところは正直良くわかっていませんがVerilogを書き換えるたびに動作が変わります。謎です。タイミング制約をしなければならないらしく、こちらのサイトを参考に設定してみたのですが、完全に解決ができているのかは不明です。

http://todotani.cocolog-nifty.com/blog/2016/12/vivado-constrai.html

FPGAは初心者なのでわからないことだらけです。Verilogを書くなんて基本中の基本、本当の敵はFPGAへの実装の部分にありました!Cのように書けば書いたとおり気を利かせてコンパイルしてくれるようなそんな世界ではなかったです。ハードウェアを想定し細かい部分は面倒を見てあげないといけません。適当に書いて適当に動くなんてことはありませんでした!

多分このあたりはハードロジックにもともと詳しい方なら問題ないのでしょうが、プログラム言語で上から下に順番で動く動作ばっかり書いてきた人にとってはあまりにも概念が違っていて毎日頭痛状態です。FPGA開発をやっていると普段使っていない部分を使っているのか、数時間でオーバーヒート状態です!

とまぁ愚痴はこのあたりにして、次です。

タイミング制約、ソースのレイテンシを全面的に見直し

結局Verilogはほとんど全部書き直しになりました。最初は後段で必要な信号、クロックは計算で算出していたのですが、これだとネストが深くレイテンシが長いロジックが生成されてしまうので、できるだけシンプル、並列、これで動作できるように変更しました。具体的には最初に必要なタイミングクロックを同時並行処理的に作ってしまって、あとはひたすらシンプルにそれを使って処理するというものです。

クロック生成部は以下の通り。美しくないコードのような気がしていますが初心者なのでこんなものです。こういうふうにお膳立てしてあげれば後段のロジックは最低限で済むというものです。必要なタイミングは最初に同時並行的に生成してしまおうということです。

以下に現状のブロック図を貼ります。デバッグ用に無駄な入出力ポートがたくさんありますが、これがないと少しいじったときに原因不明のエラーになったときに原因が見えないので現状は習うより慣れろ状態でひたすらシミュレーションで内部レジスタがどうなっているのかを検証しまくるしかありません。

自分はかなり右脳派なので、理論よりイメージ派なんです。なのでブロック図を使った開発にしています。慣れている方はコードのみでルーティングするそうなのですが、個人的には接続がわからないので最初からブロック図です。

タイミング制約はこんな感じです。これで書き方が本当にあっているのか不明なのですが、これを設定したら動いたので多分あってます。FPGAは初心者かつ手探りなので鵜呑みにせず、参考程度でお願いします。

768kHzで平均化サンプリング、192kHz出力に成功

上記の対策によりなんとか動作しました。FPGAの基本動作がようやくできたので次はようやくスプリアスとノイズ対策です。こちらはアナログの問題なので一瞬で解決です。設計回路図のとおりに部品をしっかり実装したらスプリアスとノイズの問題はきれいに解決しました。このようにアナログは試行錯誤含めてもすんなり結果がでてとても楽です。FPGAはわけのわからない挙動が多くてやばいですw とはいえこれも経験値だと思うので今のうちにFPGAを触れるようになっておき、数年後にサクサク作れれば上々でしょうね。

一応補足として48kあたりに謎の成分がありますがXLR入力ケーブルを外すと消えるので原因は外来かGND相互接続あたりのように思います。基板自身から出ているものではありません。

ノイズフロア

1kHz sine THD歪み

こちらでも書きましたが歪はDAC起因の可能性があり、ノイズシェーピング残留成分と1/fノイズがないノイズフロアで結構きれいになりました。

LTC2380-24で録音した音

このあと調子に乗って1.5MHzの動作にチャレンジしたのですが24bitを一度に取らないで8bitを3回に分ける処理を書いたらノイズまみれでまた動かなくなったので、とりあえず動く状態に戻して768kHz平均化による192kHzサンプリングによるADCの音声録音データを作成してみました。聞いてみてください。多分1.5Mhzでサンプルできたらもう少し良くなります。最初192kそのままで取ったものは素性は全然悪くないのですがちょっとだけ曇った音でした。

https://drive.google.com/file/d/1QHE9diJ3SSIYGLvyM45hDuS3Rjkd46f4/view?usp=sharing

ファイルは24bitの192kHzです。それぞれ、AK4497-DACからLynx HiloでADCしたもの、AK4497-DACからLTC2380-24でADCしたもの、PCM-501ESからLTC2380-24でADCしたものとなっています。それぞれゲインとタイミングは概ね合わせてあります。

昨今はTwitterでも音声の著作権がうるさくなっているようなので、今回は念の為私が編曲、ミキシングしている楽曲にしています。そのなかでも音質が良く、いろいろな速度と帯域の音が入り混じっているテスト向きだと思う曲を選びました。

この楽曲についてはこちらに紹介と解説を書いています。2曲め「陽だまり猫だまり」という項目以下です。今はオーディオの技術ばっかりやっていますが、これでも以前は音楽制作がメインでした…(今は昔)もう11年前の曲と考えると目眩がしてきますw

新年のミックス素材&ベスト3の追加情報

最後にもう一度書いておきますが、FPGA初心者なのでVerilogまわりは本当に適当なこと書いてる可能性があるのでくれぐれもご注意ください!

参考リンク:ブロック開発のための資料

http://nahitafu.cocolog-nifty.com/nahitafu/2016/08/vivadortlip-3d7.html

https://forums.xilinx.com/t5/Design-Entry/How-to-simulate-Block-design-in-vivado/td-p/865525

https://qiita.com/iwatake2222/items/b0f2ce7b4653bc6f32b9

https://qiita.com/s_nkg/items/f2928fb727238d14f23f

参考リンク:ノンブロッキング代入とブロッキング代入

https://qiita.com/rikitoro@github/items/7a2ee703182c3abd9f83

https://blog.goo.ne.jp/sim00/e/9b21e3d0c135f94a49a88e147e344ab5