皆様こんにちは、ドルフィンシステムの笹生です。
さて、引き続き LabVIEW FPGA の解説をしたいと思います。
なかなか本題の無線信号処理に入ることができませんが、やはり LabVIEW で FPGA を扱ううえで避けて通れないところもありますので、慌てずに解説していきたいと思います。
前回、どちらもやりたいことは同じなのに、コンパイルが失敗するものと成功するものを紹介しました。
成功したほうには処理の前後に「フィードバックノード」を挿入しており、これが成功の秘訣だとお伝えしました。
今回は LabVIEW FPGA で動作周波数の高いクロックでもコンパイルを成功させる秘訣、「フィードバックノード」の解説をします。
この「フィードバックノード」、通常の LabVIEW ソフトウェア開発でも使ったことがある方もいるかもしれません。しかしそれほど頻繁に使用しないと思います。でも、LabVIEW FPGA の開発では意識的に使用する非常に重要になるキーコンポーネントで、私はかなり多用しています。
フィードバックノード
「フィードバックノード」を LabVIEW FPGA で使用する目的は主に 3つあります。
1:データを保持する(シフトレジスタ)
2:並列処理間のタイミング合わせ
3:動作クロックの向上(コンパイル時のタイミングエラー回避)
(これを見て FPGA を昔からご存知ならお分かりかもしれません。要はフリップフロップです。)
LabVIEW のヘルプなどに書いてあることは基本的に 1 だと思うのですが、LabVIEW FPGA で開発するうえでは、2、3 の役割も大変重要になってきます。今回は主に 3 について解説します。
「フィードバックノード」で動作クロックを向上させる
なるべく話を簡単にして解説をしたいと思いますので厳密な部分でおかしなところがあるかもしれません。
より詳しく学びたい方は、FPGA の専門書は今やたくさんあるのでそちらをご参照いただければと思います。
(以下、色々たとえ話を考えていたのですが身の回りの例えでうまく表現できませんでした。すみません。。。)
演算を何もしない経路でもコンパイルエラーは起きる
例えば極端な例です。16bit の幅のデータを入力からそのまま出力に出すようにします。
演算は何もしてません。
ソフトウェアなら、単なるコピーです。データが壊れるといったことはありません。
しかし、FPGA ではコンパイルで計算された最大動作周波数以上のクロックの場合、データが壊れることがあります。
なぜか。
それは FPGA では物理的に距離が変化するからです。
FPGA のコンパイラが配線をするとき、もちろん最大限努力して全てのビットを最短距離にしようとしてくれます。しかし、物理的な限界もありますしそれぞれの経路で差がでてくるのです。
そのため、あるビットの距離があるビットの距離よりも長いといったことは当然起こりえます。
距離が違うとどうなるのでしょうか。
この例では入力16bit はきちんとそろって入力されたとします。
出力の 16bit には、下位 15bit は 10ns で到達する距離でしたが、最上位ビット 1bit だけ距離が長くなって20nsかかったとします。
(これはイメージです)
この "最大距離=最大時間" で "動作可能な最小ティック時間=最大クロック周波数" が制限されるのです。
この例であれば、最も遅い 20nsのティックのクロックであれば問題ありません。
つまり 50MHz 未満なら全ビット入力から出力に正確にわたります。
では 100MHz のクロックだったらどうでしょうか。
コンパイルはエラーになってしまうので実際に実行はできませんが、無理やり実行できたとすると最上位ビットだけデータが間に合わず、最上位だけおかしなデータになってしまいます。
つまりこのコンパイルでは、50MHz のクロック指定ならコンパイルは成功しますが、50MHz 以上のクロック指定だとタイミングエラーで実行はできないのです。
しかし、仕様だからどうしても 100MHz で動かしたい。ということもあると思います。
答えは「フィードバックノード」を入れる、です。
「フィードバックノード」はデータを保持してくれる役割があるのですが、その保持するタイミングはクロックの立ち上がりになります。そして、立ち上がり以外はその時の値を保持します。
次のクロックの立ち上がりでは新たな値を保持します。
さてこれがどうして動作クロックを向上させるための秘訣なのかというと、
距離を分割してくれるから
です。
「フィードバックノード」はクロックによって動作を規定されます。乗算やその他のプリミティブな処理は通常クロックは関係ありません。
先ほどの 16bit のデータをそのまま出力に出す例にフィードバックノードを入れてみます。
通常、コンパイラは動作周波数を大きくするようにしたいので、物理的にほぼ真ん中あたりに「フィードバックノード」を挿入しようとします。
つまり、15bit は 5ns + 5ns の距離に分割され、最上位ビット 1bit は 10ns + 10ns に分割されます。
こうすることで、最も長いデータパスは 10ns になり、100MHz でコンパイルが成功します。
(あくまでイメージです)
同様にして、前回の例でいうと
「フィードバックノード」が入っていない場合、入力から出力までの処理時間と経路距離がそのまま動作周波数として計算されるため、高い周波数ではタイミングエラーとなってしまいます。
そして、「フィードバックノード」を入れたほうでは、処理時間、経路距離が分割されるため、動作周波数も高い周波数でコンパイルが成功するわけです。
まとめ
高い動作周波数で動作させたいときには、データを経路を分割するために「フィードバックノード」を入れることで解決します。
コンパイルで起きるタイミングエラー、もし起こった場合どこで起きているのかわかればそこに「フィードバックノード」を入れることで修正ができそうですよね。一応コンパイラの「タイミング違反の調査」で調査できるのですが、表示される部分がそのまま本当に原因ではないことがあったりします。(むしろ表示された場所じゃないことのほうが多かったりします)
タイミングエラーが起きてしまった場合には、「タイミング違反の調査」の場所以外にも、新しく追加したところの処理が多くないかなどを見ていく必要があると思います。
意外と本来動作速度と関係がない、動作周波数は遅くてもいい制御器、表示器にフェードバックノードをつけると改善されたりすることも。
この辺りの改善ノウハウは経験によるところが大きいです。
0 件のコメント :
コメントを投稿