電子回路わからん日記

にゃーんと言いながら電子回路いじってます

リアルタイムDSDコンバータのHDL記述

新年明けましておめでとうございます。
2022年もド素人電子工作アカウントのAUDIYをよろしくお願いいたします。

今回から前回のシミュレーション結果をもとに、いよいよFPGAにリアルタイムPCM-DSDコンバータを実装していきたいと思います。


ΔΣ変調のブロック図

さて、前回シミュレーションしたPCM-DSD変換ですが、

audio-diy.hatenablog.com

 

これをリアルタイム実装するにはΔΣ変調をFPGA上に実装する必要があります。

ΔΣ変調のブロック図としては、個人的に下記ブログが最も理解しやすいと感じました。

xx3stksm.hatenablog.com

 

積分器のブロック図含めて描かれています。

今回はこれをFPGAに実装するためにVerilogコードにしましたので解説していきます。


I2S-パラレルPCM変換

これは今回のリアルタイムDSDコンバータを作るモチベーションとなったものですが、Verilogコードそのものの公開は初めてと思います。

github.com

 

HDLを書いたことの無い方のために言葉で説明しますと

  • BCLKの立ち上がりエッジに合わせてデータを64bit分(Lch: 32bit、Rch: 32bit)ストック&LRCKを1BCLK分遅延させる
  • 遅延させたLRCKの立ち下がりエッジに合わせて64bitを上位32bit(Lch)、下位32bit(Rch)に分離して出力
  • RST_I信号がLowとなった際には出力と内部の保存データを全て0にする

という機能を実現しています。

これによりLRCKをワードクロックとしています。


微分

ΔΣ変調の「Δ」に相当する部分です。

github.com

デジタルにおける微分は「入力値から1サンプル前の微分値を引き算する」ことによって実現していますが、今回は上記のブロック図に則り引き算のみを担当します。

 

1サンプル前の数値は、後ほど紹介するDSM_MAXIMIZER.vが担当します。


積分

ΔΣ変調の「Σ」に相当する部分です。

github.com

 

微分器の反対なので「入力値と1サンプル前の積分値を足し算する」ものです。

ただ足し算だけ繰り返すといずれオーバーフローしますので、足し合わせる計算結果は1ビット→シフトします。


量子化

積分した結果を1ビット信号として出力します。

積分した結果が正であれば1、負であれば0を出力すれば良いのですが、

github.com

上記のコードの通り最上位ビットを反転すれば良いです。

 

なぜかというと、符号付き整数においては最上位ビットが符号ビットであり、

0: 正の整数

1: 負の整数

であるためです。

 

出力したい結果は

正の整数なら1

負の整数なら0

なので、0→1、1→0つまり最上位ビットのNOT演算で実現できます。


遅延+振幅の最大化

量子化された結果を微分器へフィードバックするためのモジュールです。

ここで微分のために1BCLK分の遅延を加えています。

 

量子化された結果は1bitだと1か0となり、そのままでは入力と計算しても正しく微分できないので、これをPCM信号の最大振幅とします。(ブロック図上でよく「DAC」と表記されている部分です)

github.com


配置配線

筆者はQuartusで開発していますので、ブロック図を描いて機能を実現します。

github.com

 

これを論理合成すると下のような回路図になりました。

github.com

 

ひと通り見たところ間違いはなさそうですが、どうでしょうか?

ブロック図は下記リンクのVerilogコードに変換済ですので、VivadoやDiamondをお使いの方でも合成・配置配線できるかと思います。(Intel固有IPも使っていません。)

github.com

 

使って遊んでくれると嬉しいです。


次回は実際にFPGA上で動作させて出力波形をオシロスコープで覗いていきたいと思います。