Posts Tagged with "Vivado HLx"

既に発行済みのブログであっても適宜修正・追加することがあります。
Even in the already published blog, we may modify and add appropriately.

グラフィックメモリの設計

posted by sakurai on July 23, 2019

ある目的があり、グラフィックメモリシステムの設計を再度行います。前回設計しているので、パラメータを少々変更するだけで簡単にできそうな気がします。

さて、設計仕様は、昔の8bit PCのVGAをエミュレートするものです。640dotx200dotのRGB各1bitの8色という仕様ですが、横に対して縦のドット数が小さいですね。VGAタイミングのサイトだと640x400というものはあっても、640x200というサイズはありません。

画面が横長に歪であることには理由があり、アドレス空間が16bitであることが関係していると思われます。640x400にすると、RGB各1bit(2^3=8色)だと、メモリに対して8bitアクセスの場合、96,000アドレスとなり、アドレスラインは17bit必要となり、通常の8bitマイコンの16bitアドレス空間として1bit足りません。しかたなく解像度を半分の640x200にすれば、3原色で48,000アドレスとなり、アドレスラインは16bit空間に入ります。

先のFIFOを用いたデザインを再利用して、タイミングだけを変更しようとしたのですが、再検討ついでにFIFOが削除できたので、そのデザインを再利用します。これだと計算が簡単で、dual port memoryで分離されている非同期クロックドメインであるため、ビデオ系のタイミングしか検討する必要がありません。

図%%.1
図133.1 グラフィックタイミング設計用ブロック図

画面構成が640x200なので、それに基づき前回と同じSVGA(800x600)のタイミングで設計することにします。

Space Invadersの画面設計を示します。左が論理画面、右が物理画面です。SVGAの物理画面の中央に論理画面を配置し、適宜拡大します。論理画面が256x256と小さいので、縦横2倍の拡大表示を行います。

図%%.2
図133.2 Space Invadersグラフィックタイミング設計図

次に今回の画面設計を示します。SVGAの物理画面のタイミングは同じで、論理画面のサイズが異なり、縦のみ2倍の拡大表示を行います。
図%%.3
図133.3 今回のグラフィックタイミング設計図


左矢前のブログ 次のブログ右矢

posted by sakurai on July 22, 2019

前稿で設計したグラフィックディスプレイコントローラですが、あとから振り返るとFIFOが無駄であることに気づきました。早速リファクタリングします。

リファクタリング前のクロックドメインが3つあるのに比べて、リファクタリング後は2つに減っています。それだけでなく、FIFOとメモリをリードしてFIFOに入れる回路の2つを削減しています。これはdual port memoryが本来FIFOの役割を果たすためです。

図%%.1
図132.1 リファクタリング前の回路

図%%.2
図132.2 リファクタリング後の回路

FIFOとメモリ読み出し回路を削減し、メモリ読み出し回路から出ていたメモリアドレスをグラフィックコントローラから出す変更により、問題なくリファクタリングが達成できました。


左矢前のブログ 次のブログ右矢

Qiitaに投稿しました

posted by sakurai on July 13, 2019

FPGAの設計トライアルとしてスペースインベーダを取り上げたブログ記事を書いてきましたが、最初はAvnetのMicroZedボードで、PMOD-VGAとPMOD-I2Sのインタフェースを購入して、入力はボード上のスイッチを使用していました。

開発がほぼ完了した段階で、AvnetからUltra96 ボードが発売されたので、さっそく購入し移植しようとしましたが、Ultra96 はPMODインタフェースを搭載していないため、インタフェースボードを設計せざるを得なくなりました。

そのため、Eagleを使用して、PCBを設計し、さらに格安でPCBを製造するベンダを探しました。

この経緯をQiitaに投稿しました。合わせてYoutubeにも上げています。


左矢前のブログ 次のブログ右矢

posted by sakurai on January 16, 2019

デジタル的に出力すればOKのグラフィック系と異なり、アナログ系のオーディオ系は正しく動作させるのに案外苦労が必要でした。これだけでなく、リアルタイム性やノイズ防止の考慮を含めるともっと大変でしょう。

出来上がったサウンド系階層のブロック図を図79.1に示します。これはソフトマクロで、中にステートマシン、サウンド格納用ROM、パラシリ変換ユニットから構成されます。

図79.1
図79.1 サウンド系階層ブロック図

基本的に左側のステートマシンが、外部から与えられた音色コードに従い、右上のサウンド格納用ROMから8bitPCM wave情報を読み出し、それを右下のパラシリ変換ユニットを用いてDAC用シリアルデータに変換します。

サウンドの難しい点は演奏終了以前に割込みが入ったらどうする等の、時間的な仕様を定義するところです。本来は同時発声チャネルを複数用意し、サウンドを重ね合わせれば良いはずですが、今回は優先順位表(図79.2)を作成し、優先度の高いサウンドが、演奏中の優先度の低いサウンド演奏を中断させる仕様としてみました。優先度の高いサウンドを待たせるとおかしくなるためです。例えばインベーダの移動音が、弾の発射音を中断させても違和感を感じます。マスキング効果を考えれば、重畳しなくても特に問題ないことが実験により判明しました。

図79.2
図79.2 サウンド優先順位表


左矢前のブログ 次のブログ右矢

posted by sakurai on January 6, 2019

ここでアナログ波形をDSOで取得してみます。図78.1のような波形が取得されました。青がシリアルDACデータ、黄色がDACの出力のアナログ波形です。

図78.1
図78.1 DSOアナログ波形

一方で、サウンドデータをAudacityで開いてみると、図78.2のような低音の波形となっています。これはインベーダの進行音です。

図78.2
図78.2 Wave波形

シミュレーション波形やwaveデータ波形は図78.2のようであり、アナログ波形はこのようでなければならないはずなのですが、図78.1ではある閾値以上と以下で波形が折り返されているようです。ここで思いつくのがMSBが反転しているのではないかということです。ここまではwaveデータをそのままDACに入力すれば良いと思っていたので、データ構造を調べてみます。すると、以下の事がわかりました。

  • 8bitPCMデータは符号なし
  • 16bitPCMデータは符号付き

従って、パラシリ部で8bitから16bitへ伸長する際にLSBへのゼロ詰めだけではなく、符号なし⇒符号付き変換を実施しなければなりません。ハードウェアにMSBを反転する修正を加えたところ、図78.3のような正しいアナログ波形が得られました。

図78.3
図78.3 DSOアナログ波形

破裂音はロウパスフィルターが入っていないことだと考えていましたが、波形を見て一目瞭然、符号付き⇒符号なしの変換が抜けていたことが根本原因でした。これで音楽データであってもきれいに再生できるはずです。


左矢前のブログ 次のブログ右矢

posted by sakurai on December 28, 2018

破裂音原因解析

シミュレーション波形を確認すると、アナログ波形がなんだか尖っています。アナログとデジタルの一致性が必要で、そのためにはサンプリング周波数の1/2以上の周波数をカットする必要があります(標本化定理)。

図77.1
図77.1 シミュレーション波形

周波数帯域を制限するには22.05KHz以下をカットするロウパスフィルターを入れる必要がありますが、まずDACチップのデータシートの参考回路図を確認します。

図77.2
図77.2 DACデータシート

図77.2のとおり、アナログ出力にRとCで構成されるロウパスフィルターが入っています。

次にそれがどのように実装されているかを、PMOD DACモジュールのデータシートで確認します。

図77.3
図77.3 PMOD DACモジュールデータシート

出力のロウパスフィルターが入っていないことがわかりました。 サンプリング周波数は44.1[KHz]であったので、ロウパスフィルターの時定数を決定します。 図77.2にCを求める式が書かれており、 $$ C=\frac{50+470}{4\pi\cdot 44.1\cdot 10^3\cdot 50\cdot 470}=40[nF]=0.04[\mu F] $$ となることから、アナログ出力に40nFのキャパシタ(0.04$\mu$Fのセラコン等)を挿入すれば良いことになります。


左矢前のブログ 次のブログ右矢

posted by sakurai on December 20, 2018

データ変換

ROMに入れるデータをVivadoで読めるCOEフォーマットに変換します。以下はwaveの16進ダンプファイルをCOEのデータ部に変換するコマンドです。これにヘッダとトレーラを付ける修正を行いROMデータとします。

$ od -An -t x1 -v input.wav|sed -e 's/ /,/g' >output.coe

シミュレーション

詳細設計に基づきシミュレーションを実施し、波形を確認し、不具合を修正するというループに入ります。 Vivadoはアナログ波形も表示可能であり、シミュレーションでアナログ波形を確認します。

もちろん全体だけでなく、細かいクロック毎の動きを見ていきます。ステートマシンが期待通りのステート遷移をしているか、LRCLKとシリアルビットデータの並びはDAC仕様に合っているかなどを見ていきます。

図76.1
図76.1 シミュレーション波形

実験

FPGAにビットファイルをダウンロードし、実験します。STARTスイッチを押すと、それなりの音が出ますが、元のファイルをPCで再生した音と若干異なるようです。なにか破裂音が混ざっています。元の音はインベーダが破壊された時の音なので、破裂音が混ざっていても構いませんが、もし音楽だったら聴くに堪えないでしょう。


左矢前のブログ 次のブログ右矢

posted by sakurai on December 10, 2018

設計指針

設計指針を記述していきます。

  • サウンドデータはwaveフォーマットでROMに8bit単位で格納する。フォーマットは非圧縮PCM、8bit、モノラル、11.025KHzサンプリング
  • FSMはFSMCLKで動作する。FSMCLK=176.4KHz(=1/8*SCLK)。
  • 8bitサウンドデータの読み出しは、FSMからアドレスを与えることで行う。
  • FSMから並列直列変換(以降パラシリ)にROMデータを供給する。
  • パラシリでは8bitデータをDACの要求する16bitデータに伸長する。具体的にはROMデータを上部8bitに詰め、下部8bitはゼロを詰める。
  • パラシリのシフトはSCLK(=BCLK)で行う。SCK=1.4112MHz。
  • パラシリの1フレームはLRCLKの立下りで開始する。LRCLK=44.1KHz(=1/32*SCLK)。
  • 変換されたシリアルデータは1SCLK遅らせてDACに出力する。

アーキテクチャ設計

以上の指針からブロック図を書くと以下のようになります。

図75.1
図75.1 サウンドコントローラブロック図

詳細設計

上記ブロック図(アーキテクチャ設計)をもとに、ブロック内部をRTLで記述したものを下図に示します。 SCKはシリアルクロック(=ビットクロック)ですが、内部クロックモードを使用するために、コンスタント出力としています。基本的にZynqを除き、ブロック図と一致しています。

図75.1
図75.1 Vivadoのブロック図


左矢前のブログ 次のブログ右矢

posted by sakurai on November 30, 2018

前回の続きです。

設計制約

設計制約をリストアップします。

  • LRCLKの1周期に対し、L=16bit, R=16bitの32bitのシリアルデータが必要であり、シリアルデータはSCKでシフトされるので、SCK=LRCLK*32。ただしこのSCKは、DACに供給しなければDAC内部で発生されます。
  • データフォーマットより、サンプリングレートは16進数で16'h2b11=11025、すなわち11.025KHz。LRCLK=Fs(サンプリング周波数)とのことで、LRCLK=11.025KHzとしたいところですが、下図において、LRCLK=11.025KHzが存在しないので、データのほうを4倍のインターポレーションすることにし、LRCLK=44.1KHzとします。
  • 上記関係式よりSCK=1.4112MHz。
  • マスタークロック(MCLK)は下図のように、256, 384, 512, 768, 1024倍等の任意性がありますが、ここでは256倍の11.2896MHzを使用します。

図74.1
図74.1クロック表

タイミングチャート

クロックに関する設計制約がだいたい解決したので、タイミングチャートを書いていきます。基本的にハードウェアベースのサウンド出力であるため、FSMによるフォーマット解析を行います。タイミングチャートは以下のとおりです。

図74.2
図74.2 タイミングチャート

ステートマシンのクロックFSMCLKは図74.2のように、ステートアドレス、ステートデータ、データアドレス、データデータの4クロックで1サウンドデータの読み出しになることから、4*FSMCLK=2*16*SCLK、これよりFSMCLK=176.4KHz。

DACが要求する16bitデータ×2ch(L, R)の32bitデータについては、データソースが8bitモノラルであるため、8bitデータをMSB側に詰め、残りは0詰めし、16bitとします。LとRには同じデータを供給します。

インタポレーションのやり方は線形補完する方法と、同じデータを繰り返す方法がありますが、もともと16bit@44.1KHz表現可能なDACに対して8bit@11.025KHzという荒い音質であることから、同じ32bitデータを4回繰り返すことにします。

以上で設計制約から来るクロック周波数とタイミングチャートが確定したので、これに基づいてFSMを設計します。


左矢前のブログ 次のブログ右矢

posted by sakurai on August 20, 2018

次はサウンドです。音を出すには可聴周波数帯域の適当な振幅のアナログ信号を出力します。そのために前述したPMOD-I2SというDACが必要になります。

製品データシート: https://reference.digilentinc.com/_media/reference/pmod/pmodi2s/pmodi2s_rm.pdf

使用DACデータシート: https://www.mouser.com/ds/2/76/CS4344-45-48_F2-472818.pdf

このデータシートによればステレオの24ビットオーディオDACとのことで、ゲームサウンドには高級すぎますが、それほど高価ではないのでこれを使うことにします。インタフェースはI2Sというシリアルデータです。 マニュアルに掲載されているシリアルデータフォーマットを次の図に示します。

図54.1

16bitデータ2ch(L, R)の32bitデータをシリアルでDACに供給しますが、注意点は図のように1ビットズレていることです。

入力としては、waveファイルをデコードし、シリアルデータを出力するようなモジュールを作成します。以下に入力のwaveフォーマットを示します。 http://sky.geocities.jp/kmaedam/directx9/waveform.html

このwaveをデコードするFSMを設計します。以下にサンプルのwaveフォーマットを示します。

図54.2

入手したwavファイルのサンプリング周波数とデータ精度がバラバラで、ハードで扱うには厳しいので、全て11.025KHz、8bit、Mono、メタデータ無しに変換しておきます。そのコマンドは以下のとおり。

$ ffmpeg -i input.wav -ac 1 -ar 11025 -acodec pcm_u8 -fflags +bitexact -flags:v +bitexact -flags:a +bitexact output.wav

次回に続きます。


左矢前のブログ 次のブログ右矢


ページ: