TK80/BSの
シンセシステムを復活/拡張したい〜
その41
FPAGシンセの調整、動作確認
2019年
8月10日
先週のDDSのアドレスカウンタをゲート信号でクリアするロジックですが、VivadoのILAで動作を確認しておきます。アドレスカウンタは波形表示して確認しました。DCAの出力はこれより約1mSec後なので、プチ音対策にはなりません。
旧アナログ+デジタルシンセのトーンホイールオルガン似の音源と音程を合わせるために1オクターブ上げるスイッチを追加します。ロジックを変更して動作テストを行います。動作良好です。MSP430のUSB−MIDI変換器で1オクターブ下げる設定にすると、出力と2つの音程が一致します。
動作は問題無いので、パネルに5mmの穴を開けてスイッチを取り付けます。レタリングの追加は無しです。
8月11日
オクターブ切り替え機能を追加したロジックで動作確認します。BWV593を録音してみました。画像をクリックすると約3Mバイトのmp3ファイルをダウンロードします。
次のプロジェクトの予備調査です。HLSを使うとDMAが簡単に作れます。と言うか、FPGAはハードウェアなので、メモリをアクセスするロジックは全てDMAになる訳です(笑)。ARTYボードには256MバイトのDDR3が載っていますが、FPAGシンセと以前に作製したDDSトーンジェネレータ(この辺で作製を開始しています)の両方とも未使用です。何か、もったいないです。DDSトーンジェネレータのロジックを使って、下のブロック図のウエーブテーブル音源を作製する予定です。テーブルにトーンホイールデータを使えば、トーンホイール似の音源にもなります。破線の枠内が1チャンネル分のテーブル音源で、テーブルは予めパラメータ設定器を介して、PCからDDR3に転送しておく必要があります。青色の矢印がDDR3からテーブルを読んでデルタシグマADCに転送するパスです。アナログ出力はFPGAシンセの外部入力に接続します。8chに増設するには単純に8個接続すれば良いと思われます。これはAXIインターコネクト内にバス調停機能があるためです。仮に16ビットのテーブルを8KHzで256倍のサンプルで8チャンネルを出力するとすると、2*8K*256*8=32.768Mバイト/Secで転送する必要があります。
下図のようにGateに合わせて、DMA転送します。音声を例にするとSt(スタート)からRs(リピートスタート)の1つ前までが子音、Rs(リピートスタート)からRe(リピートエンド)までが母音になります。RsとRe間は短くても良く、極端には1周期分でも良いです。ただし、サンプリングデータからこの3つのアドレスを抽出するのは結構手間です。テーブル出力はEGとDCAを使って振幅制御します。
下はここを参考にして作成したリピートDMAです。設定したいインターフェースに合わせて引数をプラグマ指定します。リピートDMAの動作はゲートが立ち上がったらスタートアドレスからリピートスタートの1つ前まで1回だけDMA転送を行い、その後はゲートが再度立ち上るまでリピートスタートからリピートエンドまでを繰り返しDMA転送を行います。トーンホイールなどの場合はリピート部のみで単に繰り返しですが、サンプリング音の場合は短いメモリで長い音を出すためにリピート部が必要です。各アドレスは予め調べておく必要があり、マイクロブレーズからAXI−Liteを介してレジスタ設定します。
100MHzで動作します。
ループ内に最適化指示子を入れて速度とリソースを設定します。ループ内をパイプラインに指定にした時のリソースです。
この時のレイテンシです。
ループ内をデータフローを指定した時のリソースです。
この時のレイテンシです。使用するリソースは減りますが、レイテンシは4倍近く長くなります。テストベンチで255+255+255=768ワード転送しているので、約5.4クロックで16ビット(1ワード)転送しています。これは100MHzで動作させると17.8Mワード/Secなのでバイトでは35.6Mバイト/Secになり、上の計算で出た32.768Mバイト/Secを上回ります。実際にはオーバーヘッドがあるので、これよりも遅くなると思われます。ただ、8チャンネル全てが8KHzで出力されることは無く、DMAの次段のFIFOで緩衝されて通常の使い方では正常に出力されると思われます。別の問題として、HLS内ではデバッグモードとして、一定転送後テストベンチに戻るようになっています。実際にはゲート信号で制御し、この関数は終了することはありません。テストベンチにはこの記述が出来ないです。"no return function HLS testbench"で検索するとこれが見つかりました。
8月17日
FPGA
シンセの方はとりあえず完成なので、パラメータ設定器の作り込みを行います。通常使う”NOM”モードでは、変更したパラメータを8チャンネル一括でフラッシュのテンポラリにセーブできます。電源投入時にセーブしたパラメータを作業メモリとFPGAに転送して立ち上がります。
各チャンネルのパラメータを管理するチャンネルメモリモードを追加します。右側のロータリスイッチを”
CHAN”にすると、指定したチャンネルのパラメータ(64バイト)をフラッシメモリ上の64個のチャンネルメモリから選んで、セーブ、ロードできるようにします。ロータリエンコーダのP1、P2を使ってユーザインターフェースを作りました。丸1日(12時間)かけて、そこそこ動くようになりました(笑)。
ウェーブテーブル音源の予備調査の続きです。FPGAマガジンのNo17を参考にDDSトーンジェネレータのロジックにDDR3を追加します。MIGを追加すると、新しいリセットも自動的に追加されます。
そのままでは合成時にエラーが出ます。原因はDDSトーンジェネレータの外部周波数変調用のXADCとDDR3のキャリブレーション用の温度センサのXADCが競合していためです。外部入力のXADCと温度センサのXADCを共用することもできるようですが、WEBを検索するとこれがヒットしました。XADCの温度センサの代わりに定数を入力する方法です。MIGを再コンフィグレーションして温度センサをディゼーブルにします。
MIGに新しく、温度入力端子が追加されます。
IPの追加で”CONSTANT”を選んで、ビット幅を12ビット、定数を2509に設定し、上記の温度入力端子に接続します。これで合成、インプリできるようになりました。
DDSトーンジェネレータのブロックデザイン全景です。変更点は赤枠で、クロックジェネレータにDDR用の200MHzと166MHzのクロック追加、MIGとリセット、CONSTANTの追加です。MIGの先にDDR3が接続されます。右下の緑枠がDDSトーンジェネレータのIPです。
DDSトーンジェネレータ(myip)の部分を拡大してみます。MicroBlazeからのレジスタアクセス用のAXI、MC80+バス、外部周波数変調アナログ入力、GPIO,64倍のDDS出力があります。テーブル音源ではDDS出力を64倍から256倍に上げ、転送開始のトリガ出力を追加する必要があります。
ブロック図中のオレンジ色枠のMIGとDDR3が追加できました。
8月21日
会社の休み時間を使って組み込んだDDR3のテストを行いました。FPGAマガジンでは先頭の8ワードに書いて読み出していますが、少しプログラムを修正してテスト範囲を広げます。ボードは当初FPGAシンセ用に使っていた旧版のARTY(35T)です。
SDKを起動してDDSトーンジェネレータのプログラムの先頭にメモリテストプログラムを追加しました。
ビルド後、FPGAに書き込み、Teratermで確認します。HelloWorldと先頭のライトです。
リードに切り替わったところです。DDSトーンジェネレータ部はテストできませんが、DDR3は正常動作しているようです。
8月24日
マルツで購入したアルミケース2種と3.5mmジャック、20ピン、16ピンのフラットケーブルコネクタが来ました。
ついでに購入したPSoC5LPボードです。
モノタロウのフラットケーブルでです。
アマゾンで購入のFPGAマガジンです。OpenCoreのUSBデバイス1.1をFPGAに組み込む記事が載っています。ただ、少し古いISEとSpartan−6用です。
TK80からFPGAシンセの動作確認を行いました。ついでに旧シンセの動作確認を行いましたが、DCO1のミキサとDCO7の調子が悪いです。
購入したフラットケーブルとコネクタでUSB−MIDI変換器のベロシティ信号を分岐する基板を作製しました。上記のアルミケースに組み込む予定です。
8月25日
一応完成しているFPGAシンセのロジック使用量を確認しておきます。DCAのゼロクロス出力、フロントパネルのスイッチで音程を1オクターブ上げるロジックを追加した版でスライスの使用量が97.92%です。
デバイス図です。下部に少し空きがあります。DDSトーンジェネレータのように半音単位でパラメータ設定器から音程をオフセットする機能を追加したいのですが、容量が足りるか調べてみます。
ウェーブテーブル音源の続きです。ゲート出力とDMAトリガ出力を追加したDDS部に上記で作成したリピートDMA、AXIストリームFIFO、デルタシグマDACを組み込んで、ブロックデザインを作りました。
HLSで作成したリピートDMAとコアジェネレータで作成した16ビット深さ1024のAXIストリームFIFOです。
必要な信号線を追加したDDS
(myip)とデルタシグマDACです。DDSの出力クロックは64倍のままですが、後で256倍に変更します。
リピートDMAのAXI−Liteのアドレスはブロックデザインのアドレスエディタで設定します。0x44A20000に設定しました。
リピートDMAの引数に割り当てたられた各レジスタのアドレスは自動生成されたドライバのインクルードファイルで確認できます。リピートスタート(rp_start)はオフセット0x18、リピートエンド(rp_end)がオフセット0x20です。DMAのスタートアドレスはポインタ渡しなのでレジスタマップには出てきません。
8月31日
Aitendoで購入した128x64ドットLCDと変換基板のセットです。次のプロジェクト用です。以前はFFC変換基板に無理にコンデンサを取り付けていたのですが、この変換基板はコンデンサ用のパターンがあり、四隅に固定穴もあります。以前の変換基板はここ。
こちらはユニバーサル基板とマイクロUSB変換基板です。
パラメータ設定器にPC−USBモードを実装する準備です。CDCのサンプルコードから1Kバイトのデータを受信するプログラムC2を修正してチャンネルメモリのサイズの4Kバイトに修正します。
PC側に4Kバイトのバイナリデータを用意します。
Teratermのファイル転送機能を使って4Kバイトのデータを送信します。正常に受信できました。
パラメータ設定器にシステムメモリモードとPC−USBモードの実装を開始しました。システムメモリモードはチャンネルメモリモードで設定したチャンネルメモリ番号を8チャンネル分集めてグループを作り、フラッシュメモリにライト/リードします。システムメモリの容量は64個です。大体80%くらいできました。PC−USBモードはチャンネルメモリ/システムメモリをMSP430のUSB−CDCを使ってPCにライト/リードします。現状ではライトはTeratermへテキストで転送し、コピー&ペーストでテキストファイルを作り、リードは予備実験と同様にテキストをバイナリに変換した後、Teratermのファイル転送機能で転送します。2つのモードは丸2日かけて約80%実装できました。動作後にXMODEM/1Kプロトコルを実装予定です。
9月5日
XMODEM/1KにはCRC16の計算が必要です。ここにコードがありました。また、XMODEM/1Kの送受信の手順がここにあります。
早速、上記を参考にプログラムを作成してみます。A〜HまでのCRC16を計算します。
Cygwinでコンパイルして、実行します。結果は”10D1”です。
WEBを検索すると、ここにCRC検算サイトがありました。アスキーモードにしてA〜Hを入力して計算します。Cygwinの結果と一致することを確認しました。