2015年1月12日月曜日

ZYBO 18 ( I2S コントローラの作成 9 )

初回動作が旨く行かない場合がある件は、I2Sコーデックの初期化の問題とRTLのバグだった。
また、リミットサイクルについては正弦波テーブルの値を若干小さくしてみることにした。
具体的には本来の値を0.9999999倍した。

以下はテーブルのデータを生成するプログラム。

生成されるデータ ROMの初期値としてロードするため、32bit floatをhex形式で出力している。
左が本来の値で、右が縮小値



今のところこのテーブルで旨くいっている。

現状のプロジェクトのアーカイブを以下に置いた。
https://drive.google.com/folderview?id=0BynL4T1Zsl44UFBsMFVLZWRGVTQ&usp=sharing

https://github.com/BravoFpga/I2S-control-IP-for-ZYBO-zynq-

リポジトリをGitHubに変えました。 (2015/1/31)


2015年1月4日日曜日

ZYBO 17 ( I2S コントローラの作成 8 )

AXI マスタ側は一応動作するのだが、初期化の部分に問題があるようで初回動作が異常(ノイズ混じりの音になったり、再生スピードが遅く感じる)な場合がある。問題の発生頻度は起動直後が高く、一度正常に再生すると以降は安定になる。リセット周りに原因があるような気がしている。

正常動作時

前回まではwavファイルのデータをテキストに変換しCプログラムの配列としてハードコードしていたのだが、この方法は何かと不便だ。何か良い方法は無いか調べたところ、xilffsというドライバを使うとOSのないベアメタル環境でもFATフォーマットのSDカードの読み書きが出来ることが判った。そこで、 wav ファイルをFATフォーマットのSDカードに入れておいて、そこから順次メモリに読み込んで再生するように変更した。
xilffsを使うためには以下のようにBSPを設定する。


xilffsの使い方は、Vivado_SDKのインストールフォルダ下にexampleがある。


これを参考にして以下のようなプログラムにした。

この様にして色々な曲調のデータを再生させてみている。
表示されるスペクトルの変化と音の変化がほぼ完璧に同期している。また、これは思い込みかも知れないけど、スペクトルの変化具合・・・というか絵から受ける印象も曲調に一致しているようで、なかなか面白い。

そんな感じで色々な曲を連続再生して見ていたら問題が見つかった。
前回dft_ip作成時に発生した現象と似た現象が発生している。多分これは、リミットサイクルノイズだと思う。実機と同じように複数のwavファイルをCモデルで処理させたところ同様の結果になった。単精度浮動小数演算器で計算しているとは言っても量子化ノイズは完全にゼロになる訳ではないのでこうなるのは当たり前かも知れない。アキュレータで積算するときに若干の縮小係数を掛けるとか、一定サイクルでアキュムレータをクリアするとか、ある閾値以下の場合に0にするとか何らかの対策が必要なようだ。ただ、闇雲にやっても仕方ないので、当面は1曲毎にアキュムレータをリセットすることにした。




2014年12月28日日曜日

ZYBO 16 ( I2S コントローラの作成 7 )

AXI マスタ側の動作確認はまだやっていないが、dft ipの動作を先に見たくなったので、dft ipやdvi_encも追加し、AXIスレーブ側・つまり、レジスタ経由で音楽データを書いて動作させてみた。

VivadoのBlock Designを以下に示す。

I2Sからdft、hdmiまでのデータフローを考慮してブロックを並べ替えると以下のようになる。

データはI2S_ctl_0 ➔ dft_core_0 ➔ cpx_power_0 ➔ vif_0 ➔ dvi_enc_0 と流れていく。
cpx_powerはdft_coreから出力されるスペクトル値(32bit浮動小数形式の複素数)を絶対値(√(r^2 + i^2) )に変換するモジュールである。 絶対値は16bit整数に変換し、2ポートRAMに書く。

vif は表示コントローラで、cpx_powerの2ポートRAMから値を読出しグラフ化してVGAに出力する。画面解像度はXGA (1024 x 768)にしている。

プログラムは以下のようにした。



配列 wav_tbl[] に再生させたい音楽データが入る。
時報データを再生させてみた。

旨く行った。

動作環境



今度はMozartの曲をやってみた。
ちなみに音源はColumbia University Orchestraの2001年秋の演奏によるもので、archive.orgでPublic Domaindで公開されている。(https://archive.org/details/Mozart_Symphony_40)

デジカメの動画撮影機能を使って撮影していてピントが中々合ってくれないのが困りものだが、dft ip自体は期待通りに動作している。 \(^_^)/

Cモデルで動画を作成した時はグラフの横軸はログスケールとしたが、実機ではリニアスケールになっている。ログスケールにすればもっと見やすくなるかも知れない。また、vifを通常のフレームバッファにし、且つdft_coreの出力部にAXIプラグを追加して結果をDRAMに出力して、ARMのソフトウェアで加工すればもっと気の利いた表示も出来るようになるだろう。

ということで、dft ipは問題なさそうだ。次は、I2SのAXIマスタ側の動作確認をしようと思う。

将来的にはdft ipをCで書いて高位合成してどんな感じになるかも見てみたい。


2014年12月23日火曜日

ZYBO 15 ( I2S コントローラの作成 6 )

I2S IPをvivadoでIP化してzybo_base_systemのblock designを基にして実装してみた。

SynthesisとImplementationは旨く言った。ただし、このデザインの場合AXIスレーブとAXIマスタは別クロックになっている。I2S IPはこの他にI2S I/F用のクロックでも動作する部分がある。そのため、合成制約のクロックドメイン間のfalse_path設定は以下のようにした。

Implementation後bit fileを生成し、Hardware情報をExportしてSDKの立ち上げた。
まず、手始めに以下のようなI2S IPのレジスタを読んで表示するプログラムを書いて動かしてみた。


XPAR_I2S_CTL_0_BASEADDRはxparameters.h内で定義されているI2S IPのAXIスレーブポートのベースアドレスである。

値は0x43C00000になってるのだが、Eclipseでは何故か0x43C10000と表示されてしまう。

プログラムを実行させてデバッガで確認するとpI2Sの値は0x43C00000になっているのでEclipseのバグ(?)なのかも知れない。

プログラムを最後まで実行させると以下のようにレジスタ値が表示された。

レジスタの値がRTLのspec値と一致しているのでリード出来ているようだ。




2014年12月14日日曜日

ZYBO 14 ( I2S コントローラの作成 5 )

ADCの経路のシミュレーションによる確認が出来た。
ADC側のデータパスもDACと同じようにレジスタ経由のパスとDMAによるパスがある。

以下はレジスタ経由の場合のシミュレーション波形
i_CODEC部の正弦波はI2S CODECモデル内で発生させている波形で、これをシリアライズしてI2S_RECDATに出力している。 最下段の正弦波はI2S IPのレジスタ経由で取得した値である。
ベクタは以下のように書いた。
ADC_IRQ割り込みを使って1サンプルづつデータを取得している。

以下はDMAの場合の波形
DACのDMA機能シミュレーション同様、Non circulation モードとCirculation モードを見ている。

ベクタは以下のように書いた。

codecモデルは以下のように書いた。

ADC, DAC双方のシミュレーションによる確認がとれたので、次はVivadoでIP化して合成してみようと思う。

2014年12月7日日曜日

ZYBO 13 ( I2S コントローラの作成 4 )

レジスタ経由(AXI-SLAVE経由)でのDAC出力のシミュレーション確認は出来たので、今度はDMA(AXI-MASTER)側のシミュレーション確認を行った。 I2S側がAXI-MASTERになるので、AXI-SLAVEのモデルが必要になるが、これは以下のようなビヘイビアモデルとした。 AXI I/FはVALIDとREADY信号のハンドシェイクにより情報の転送が行われるが、AXI規格では、これら2つの信号が共にHの時にハンドシェイクが成立し、その前後の信号の状態は規定されない。すなわち、相手の信号が特定の状態にあることを期待してはいけないことになっている。
本モデルでは、モデルが駆動するVALIDやREADY信号をm_XXXX_ptn配列で、ある程度ランダムに振って確認するようにした。




ベクタ
はじめにnon-circulation modeでDMAを実行し、次にcirculation modeで実行し4msec後に停止している。


波形

non-circulation modeの終了部

circulation modeでポインタが循環(END➔BEGIN)するところ

停止部


AXI-MASTERもSLAVEも自分で作っているのでどこか大きな勘違いをしている可能性もあり、実機で動作確認をしないことには安心できないが、問題なさそうな気がする。

ADC(録音)の経路はまだ確認がとれていないで、今度はそこのシミュレーションを行う。

2014年12月6日土曜日

ZYBO 12 ( I2S コントローラの作成 3 )

久しぶりに、DFT IPのCモデルを使ってみた。 このCモデルは前回DFT IP作成時に作ったもので、DFT IPのアルゴリズムをC言語で実装したものだ。 アルゴリズムと言っても、DFT(離散フーリエ変換)の式を展開(変形)しただけのものだが。 (アルゴリズムの詳細は2012年10月27日のブログに書いてある。)

Cモデルはwav形式のファイルを入力として与えると、その内容をDFTして結果をテキストファイルで出力する。出力形式は5種類を指定できるようにしていたが、今回新たにlog形式を追加した。

このアルゴリズムは1サンプル毎にスペクトル列を生成できるが、出力ファイルが膨大になるので2048サンプル毎に間引いて出力することも出来るようにしている。

また、絶対値出力の場合にはスペクトル値とともに周波数値も出力するようにした。

この出力ファイルをgnuplotとavidemux等を使って編集して動画を作ることができる。
時報のデータをDFTしてみた。
画像化の手順はこんな感じだ。
Cモデルを実行する。

すると、大量のスペクトルファイルが生成される。

これらをgnuplotでグラフ描画してjpegファイルに変換する。これは以下のようなシェルスクリプトで行っている。

このスクリプトの実行が完了すると、jpgというディレクトリ下に変換されたjpegファイルが生成されている。

次に、avidemuxでこれらの画像からAVI形式の動画を作成する。

上記のようにすると、jpg下の全てのjpegファイルが番号順に読み込まれる。
このデータは2048サンプル毎のデータであり、サンプリングレートは44.1kHzなので映像のフレームレートとしては44.1KHz/2048=21.533になるので、レートをそのように設定する。(映像(D)➔フレームレート(F))

次に、音声データを読みこませる。(音声(A)➔主トラック(M))
音声ソースを外部WAVにして、外部ファイルでwavファイルを指定してOKをクリックする。

これで映像と音声が合体できたので、AVI形式で保存する。


生成したAVIファイルはjpegとwavファイルが合成されているだけなのでファイルサイズは大きいが、ffmpeg等を使ってflvやwmv等のフォーマットに変換すれば小さくすることが出来る。(ただし、画質や音質は劣化する。)
こうやって作った映像を見るのは面白く、楽しい。
2012年のDFT IP作成時はしょうもないバグに気づかずに正常動作させるのにものすごく手間取ったが最終的には原因も判明し修正できた。ZynqへのDFT IPの実装が完了すれば、これと同様の映像がリアルタイムで見れるようになる。

ERROR: Failed to spawn fakeroot worker to run ...

なにかと忙しくてなかなか趣味の時間を確保できない。 ...orz  家の開発機のOSはLinux Mintなのだが、最近バージョンを22に更新したところ、myCNC用のpetalinuxをビルドできなくなってしまった。ビルドの途中で ERROR: Failed to spawn ...