TK80/BSの
シンセシステムを復活/拡張したい〜
その35
FPAGシンセ、パラメータ設定器の作製
2019年
2月16日
デルタシグマADCの動作確認を行います。ここを参考に回路を作成しましたが、うまく動作しません。原因はFPGAの入力が理想的な1/2VCCのコンパレータではないからです。右はザイリンクスの7シリーズの入力特性です。通常の3.3VのC−MOSレベルと同様で0.8〜2.0V間は動作が保障されません。


もし、デジタル入力が理想的な1/2VCCのコンパレータなら正しく動作することをLtspiceで確認しておきます。回路中のD−FFは閾値を電源の1/2の1.65Vに設定してあり、クロックは50MHzです。入力SIN波がデルタシグマADCでPDM信号になり、その後、パッシブフィルタで元のSIN波に戻っていることが確認できました。右の波形は下から、入力、コンパレータ入力(D−FFのD端子)、出力です。

波形の先頭付近のコンパレータ入力とPDM出力の波形を拡大してみます。

さらに拡大して、別グラフにしてコンパレータ入力と50MHzクロックの関係を確認します。コンパレータ入力のノコギリ状の波形はクロックの半分の成分(25MHz)があり、1.65Vでコンパレートされています。外部にコンパレータを設ける場合には25MHz程度の信号が扱える高速コンパレータが必要です。

2月17日
Ltspiceに登録されているアナログコンパレータをD−FFの手前に接続してみます。ライブラリから、高速コンパレータLT1720を選んでみました。

波形を拡大して各タイミングを確認します。上記の理想的なD−FFと同様の動作しています。

試しに、別の中低速コンパレータLT1081を使用すると、以下のようになりました。デルタシグマADCに付いてはもう少し調査を継続します。

パラメータ設定器の方を進めます。パネル左側の2つのチャンネルとファンクションのロータリスイッチのポジションがMSP430から正しく読めることを確認しました。

続いて、右にあるモードの切り替えスイッチです。これは動作不良で、読めていません。P8.1と8.2を使用し、4つのポジションが読めるはずですが、常時00です。MSP430F5529のP8は0〜2の3ビットで、8.1と8.2のみコネクタに接続されています。デバッガでP8の制御レジスタを確認しましたが、入力ポートに設定されており、ポートマッピングも無く、少なくともベースボードまでスイッチ信号が行っていることを確認しました。不具合の原因は不明です。

2月21日
Latticeの資料(PDF)にCPLD/FPGAにデルタシグマADCを実装する情報がありました。コンパレータの代替えとしてLVDSレシーバを使っています。

上記と同じ高速コンパレータLT1720でシミュレーションしてみます。正しく動作しています。コンパレータの代わりにLVDSレシーバが使えれば、外付け部品CR、1個つづでデルタシグマADCが実装できます。

LVDSレシーバを記述する方法を調べます。はじめに制約ファイルです。ここにLVDS_33は使用できないとの情報があります。VCCOは3.3Vのまま、LVDS_25を使用するようです。レシーバの入力が同相電圧+差動電圧/2<VCCO+0.2の範囲なら良いということです。もちろん、図中のターミネタは取り付けません。

XXX.xdcの記述です。
set_property -dict {PACKAGE_PIN xx IOSTANDARD LVDS_25} [get_ports xxx_in1_p]
set_property -dict {PACKAGE_PIN xx IOSTANDARD LVDS_25} [get_ports xxx_in1_n]
次にVerilogのロジック内にLVDSのレシーバを記述する方法がここにありました。
module xxx(
.
.
// モジュールの入出力信号の記述
input xxx_in1_p, // 差動プラス入力
input xxx_in1_n, // 差動マイナス力
output xxx_out_q1, // D−FFのQ出力
.
.
);
// LVDS入力バッファの記述
IBUFDS ibuf_din (.O(xxx_in1),.I(xxx_in1_p),.IB(xxx_in1_n));
2月23日
上記の設定でインプリしてみます。IBUFDS(差動レシーバ)がちゃんと使われているか回路図で確認します。正しく、IBUFDSが使われ、デルタシグマADCに接続されています。


続いて、デバイス図です。差動入力のピンはE15とE16ですが、E15のパッドの中にある差動レシーバが使われています。差動なので対称の位置にあるのかと思いましたが、E15の方に偏っていました。配線長の違いは問題ならないくらい小さいのでしょう。


とりあえず、1チャンネルのみで動作確認します。外部回路を少し修正します。デルタシグマADCのサンプリング周波数は100MHzです。


はじめに、SIN波、1KHz、振幅1V、オフセット1Vです。上:デルタシグマ入力、下:PDMのまま出力してパッシブフィルタ接続。正しく、FPGAで1ビットのPDMに変換できているこを確認しました。


入力の電圧範囲を確認します。SIN波、1KHz、振幅1V、オフセット1.2Vです。上:デルタシグマ入力、下:PDMのまま出力してパッシブフィルタ接続。上側の直線性が悪くなっています。


続いて、SIN波、1KHz、振幅1V、オフセット0.8Vです。上:デルタシグマ入力、下:PDMのまま出力してパッシブフィルタ接続。下側でクリップしています。このことから、入力電圧はオフセット1V、振幅1Vくらいが入力範囲のようです。


電圧範囲が分かったところで、方形波を入力してみます。1KHz、振幅1V、オフセット1Vです。下:デルタシグマ入力、上:PDMのまま出力してパッシブフィルタ接続。方形波も正しく出力されています。


続いて、周波数を高くしてみます。SIN波、20KHz、振幅1V、オフセット1Vです。下:デルタシグマ入力、上:PDMのまま出力してパッシブフィルタ接続。正しく出力されています。


ここまで、PDMをそのまま出力していましたが、FPGA内で使うにはストレートPCMに変換する必要があります。192KHzサンプルのPCMに変換してみます。ロジックは簡単で、
100M/192KHz=520.83なので、デルタシグマの521サンプル間をアップダウンカウンタでカウントします。中間値で初期化し、PDMが1ならアップ、0ならダウンカウントして、1サンプルの10ビットPCMとします。無音の時、最高速で0と1が交番します。この時アップダウンカウンタの値は初期値に戻り、中間値になります。521=10ビット弱です。1次デルタシグマで100MHzでサンプリングしても192KHzのPCMに変換すると10ビットの低い分解能となります。
SIN波、5KHz、振幅1V、オフセット1Vです。下:デルタシグマ入力、上:PDMを192KHzサンプルのPCMに変換してから、デルタシグマDACで出力して上記と同じパッシブフィルタ接続。正しく、PCMに変換されています。このアナログ入力は旧DCO(8ビット)を接続する予定なので9ビットあれば十分です。


周波数を高くしてみます。SIN波、20KHz、振幅1V、オフセット1Vです。下:デルタシグマ入力、上:PDMをPCMに変換してデルタシグマDACで出力してパッシブフィルタ接続。時間軸を拡大して192KHzのサンプルを確認します。正しく、192KHzで出力されてます。


続いて、方形波です。5KHz、振幅1V、オフセット1Vです。下:デルタシグマ入力、上:PDMをPCMに変換してデルタシグマDACで出力してパッシブフィルタ接続。問題無いです。


デルタシグマADCが動作が確認できたので、外部回路を8ch用に修正します。前段のボルテージフォロアとカップリングコンデンサを残して、抵抗とコンデンサを取り外しました。

オフセット抵抗を追加して、オフセット無しで信号が入力できるようにします。以下はLtspiceで作成した回路図です。前段のボルテージフォロアは省略しています。

デルタシグマADCを8チャンネルにするには、差動入力16ピン、出力ポート8ピンの合計24ピンが必要です。現状の外部回はPMODコネクタが2個(16ピン)しかないので、ケーブルで接続して、1個増やしました。

カップリングコンデンサとオフセット抵抗を追加したので、オフセット無しで動作確認します。SIN波、1KHz、振幅1V、オフセット0Vです。下:デルタシグマ入力、上:PDMをPCMに変換してデルタシグマDAC出力してパッシブフィルタ接続。問題無いです。


キャノンのモバイルプリンタをくれるとのことで、宅配で送ってをもらいました。Win7では正式サポートしていないようですが、ネットに繋げると自動でドライバがインストールされました。何回かヘッドクリーニングして、テスト印字できました。用紙は1枚づつ手差しです。バッテリもまだ生きているようです。

2月24日
FPGA
シンセ本体のデルタシグマADCが動作したので、パラメータ設定器の方を進めます。先週、モード設定ロータリスイッチのポートが読めなかった不具合です
が、再度確認したところ、問題なく動作しました。停止中でもCCSのレジスタウインドが正しく更新されないことがあるようで、連続更新ボタンの代わりに、ブレイクポ
イントをかけて実行後にブレイクすれば、レジスタウインドが更新されました。

Cygwin上でデバッグして作成した、LCD表示のコードもMSP430に移行して、実機で基本動作の確認しました。

7セグに表示するアルファベットの’Q’と’9’のフォントを変更しました。”QUIT.−= 1239”と表示させてみました。

ロータリエンコーダ値を7セグとLCDに表示させてみます。ロータリエンコーダ値はプッシュボタンを押しながら回転させると、+−0x10で早回しできます。ロータリエンコーダのプッシュボタンは別の使い方を予定しています。プッシュボタンの2重押し(たとえばP6を押しながらP1を押すと1チャンネルを発音する、P5を押しながらP6を押すと音色名のエディットモードに入るなど)でコマンドを遷移させる予定です。

3月2日
パラメータ設定器のメインループ内のプログラムを作成します。ロータリエンコーダ、トグルスイッチの値を表示して、FPGA本体に送信する部分です。先週もらったプリンタにプログラムのスケルトンを印刷してフローを確認します。考えがまとまらない時は印刷すると作業が進みやすいです。

パラメータ7はON/OFFのトグルスイッチが3個あります。スイッチは中点付きで、MSP430に内蔵のADC12を使って値を読み込みます。デバッグ中にスイッチを操作しなくても、図しない値になる時があります。下はスイッチの操作を行わないのに、勝手にスイッチありの処理でブレイクしたところです。パネルやロータリエンコーダを触ると誤動作する場合が多いです。

トグルスイッチの回路は左図で、コンデンサを追加してノイズ対策しました。


3月3日
念のため、ADC12のサンプリング周波数も低く設定しました。ADCはトグルスイッチの値を読むだけなので、クロックの分周を最大しました。さらに、上下判定の閾値を広げました。この週末の2日間を使ってプログラム/デバッグしましたが、思っていたより難しくメインループの処理は完成しませんでした。

3月6日
少し前にFPGAシンセ本体のLFOを修正しました。EGのなどに使えるようにゲート専用のPW波を追加しました。この信号はHLSのポインタ渡しで記述してあり、IPを組み込んだところ、rec_ap_vldという制御信号が増えていました。ザイリンクスの高位合成のドキュメントに今回と同じポインタ渡しの例がありました。

この例でも、xxに対してxx_ap_vld信号が追加されます。これはxx信号が有効であることを示します。

タイミング図で確認すると、xx信号をこのxx_ap_vld信号でラッチすれば良さそうです。

早速、ラッチ部を追加して、合成、インプリしてみました。実機がないので動作確認は今週末に行います。

Vivadoの深いディレクトリ構造や、他のオープンIPのツールを考慮すると、開発環境はLinuxの方がいいです。以下、VivadoをVMware Player上のUbuntu 16.04 LTSでHLSを動作さたところです。ここを参考に会社のWin10のPCで動作確認しました。ただし、ソースコード中の日本語コメントを文字化け無しで表示するにはUTF−8に変換する必要があります。emacasがあれば簡単に文字コードの変換ができます。

懸念事項のダウンロード用のUSBドライバはARTYボードを接続すると、以下のようにポップアップが出ます。

USBドライバをVMware側に切り替えた後、Vivadoのハードウェアマネージャを起動するとARTYボードが認識されました。2chFPGAシンセのロジックをダウンロードできることを確認しました。他にSDKとDocNviも動作しました。


