Ryuz's tech blog

FPGAなどの技術ブログ

FPGAはどこまでソフトウェアか?

はじめに

今更ながら@ikwzm氏の「一体いつから FPGA はハードウェアだと錯覚していた?」に感化されて、私なりにFPGA上で行うソフトウェア開発がどういうものかというのを再考してみたいと思います。 前置きですが、あくまですべて私見ですので、こういう風に考えてる人もいますよ、という駄文です。

ハードウェアとソフトウェア

どこのどなたが言っていたのか忘れましたが「ハンマーで壊せるものがハードウェアで、そうでないものがソフトウェアだ」という考え方に基づけば、FPGAにダウンロードする0と1の並びの「情報」を開発しているわけでして、FPGA開発は疑いようもなくソフトウェア開発だと思っています。

チップという物理的なものを開発するのではなく、チップという物理的なものはXilinxなりIntelなりの製品が既にそこにある前提での開発スタートになるからです。

一方で、先の記事で述べられているように「ブートローダーやBIOS」のようなものが時にハードウェアとして扱われる事があるのも事実と思いますし、そういう意味ではハードウェアとしてFPGAを扱う事も可能ですし、それ自体を特に否定するつもりもありません。 ハードウェア開発で培われた多くの資産や経験が活用できたりするメリットもきっと大きなものかとは思います。

そうはいっても当サイトはことごとくソフトウェア指向なので、FPGAをハードウェアとして考えた場合のデメリットとは何なのか、その逆にソフトウェアとしてのFPGAにちゃんとメリットはあるのか、FPGA登場前のソフトウェアの文化や技法などの考え方はもれなくFPGAでも当てはまるのか、などと言ったところを少し考えてみたいと思います。

FPGAをハードウェアとして考える

逆説的ですが、最初にFPGAをハードウェアとして考えたとき、すなわち従来のハードウェア(LSIとかASIC)の作り方でFPGAをとらえたときに何が違うのかを考えていきたいと思います。

断っておきますが私はソフト屋であり、ハードウェア開発はしたことが無いので、伝聞による勝手な想像は多分に含まれているかもしれません。

欠陥コスト

一つはまず欠陥(バグ)発生時のコストを考えておきたいと思います。

開発中の欠陥コスト

LSI開発やASIC開発などの物理的なハードウェアの開発は「回路をLSIとして具現化して評価できるようにする」こと自体に非常に大きなコストがかかるそうです。ウォーターフォールモデルが基本であって、手戻りの発生する欠陥の発現、再製造のコストや、納期の延長など大きな損失を生み出すようです。 各工程で、その工程で出すべきバグを出し尽くして次の工程に進めるのがウォーターフォールモデルの基本です。 そのためにシミュレーターやエミュレーターが駆使され、とにかくバグを残さない検証方法が求められてくるそうです。

もちろん同じフローでFPGAを作ることも可能と思います。そうすればハードウェアとして扱うことが可能ですし、そうやってLSI開発のノウハウをFPGAに持ち込んでいる人や組織も多数あるのだと思います。

一方で、FPGA開発は工程の手戻りで発生するコストはLSIなどのそれと比べると非常に小さいです。再合成してダウンロードしなおすだけです(もちろん関連する箇所が再テストになるのはハードウェアもソフトウェアも同じですが)。

したがって、初めからスパイラルモデルや、インクリメンタルモデルと言ったウォーターフォールモデル以外の開発手法も適用可能です。ここは物理的なものを開発する場合と、物理的なものは最初からあり、0と1の並びだけを開発する場合の大きな違いと思います。物理的なものの開発は手戻りダメージがとても大きいのです。

市場バグのコスト

ハードウェアであれば、市場に出した後に欠陥が発生すれば、ソフトウェア部の修正で回避できなければ基本的には製品回収などの大きな損失を発生させることが予想されます。 もちろんFPGAもハードウェアとして扱ってしまえば、欠陥が出たときに製品回収以外に手がないことになるでしょう。

一方で、FPGAの回路は電源投入後に何らかの方法でメモリ等からダウンロードされるものですので、投入先の市場がそれを許容する分野であれば、FOTA(Firmware Over-The-Air)のような仕組みを入れておくことも可能です。

もっと言うと、スーマートフォンのアプリのように、動的に更新されていくようなプラットフォームに乗せる事すら可能です。

品質保証

次に品質保証についてです。基本的に適用先の市場の求める品質を確保して出荷することが必要です。医療や軍事、自動車や航空機のような人命にかかわるような重要な分野では非常に高い品質を求められるでしょう。

一方で、ゲームや音楽再生、研究開発用のAIのアクセラレートと言った、多少品質に問題があっても「ごめんで済んでしまう」領域もあります。

要は

(市場欠陥で想定される損失の期待値)≦ (品質保証に費やすコスト)

となるまで品質保証(テストとか)にコストを費やしてから出荷、という事になるわけですが、その際にハードウェアとしてFPGAを扱うと、先に述べた市場バグのコストが大きいので、どうしても品質保証に費やすコストは大きいものになります。 したがって、それがペイできる「高い品質を求める市場」がメインターゲットとなってきます。

一方で、ソフトウェアの中には、「ユーザーをベータテスターにしている」と揶揄されるような製品があったり、「RC2が出るまで手を出すな」と言われる製品があったり、意図的に安定版/開発版がリリースしているものがあったり、ベータテスターを一般に募ってるものがあったり、と良し悪しは置いておいて、少なくともそういう市場も存在しています。

FPGAをソフトウェアとして運用可能になれば、こういった市場も新しいターゲットの1つになってくるのではないかと考える次第です。

FPGAをソフトウェアとして考える

ではFPGA開発をソフトウェア開発としてとらえたとき、人月の神話時代から続くソフトウェア工学の話はそのまま本当に通用するのか、という疑問も出てくるわけです。

開発手法

今どきソフトウェアをウォーターフォールモデルで開発しようという話はあまりなくなったのではないかと思います。もっとアジャイルな開発手法であったり、テスト駆動型開発であったり、アグレッシブな開発手法は多数あるかと思います。 これらはFPGA開発であっても適用可能であろうと私は考えています。

ここで

生産性 = (実装された機能による価値 - 欠陥に起因するコスト)/工数

と定義してみたいと思います。

「欠陥に起因するコスト」が大きい市場向けの開発の場合は、必然的にこれを減らすために、多くの工数を欠陥を減らすために割り当てる事が生産性を上げてくれます。 これはソフトウェアもハードウェアもない話かなと思っており、手法にかかわらず最後に欠陥を残さないように戦略的に品質の作り込みに工数投入が必要です。

ソフトウェア開発のモデルは沢山ありますので、ウォーターフォールモデルのように、単体テスト結合テストシステムテストのように下からテストしていく戦略もあれば、モデルベース開発のように設計階層ごとに先にテストするような枠組みもあるでしょうし、テスト駆動開発のようにテストの定義を先行することでテスト可能な設計を保証していくような手段もあるでしょう。 いずれにせよ、市場が求める品質に比例した品質保証コストは発生してくるのはソフトウェアもハードウェアも同じですね。

一方で、ある程度欠陥を許容してしまうような市場にフォーカスをあてると、欠陥に起因するコストよりも「実装された機能による価値」に重みが出てくるため、「如何に少ない工数でたくさん価値ある機能を実現するか?」という話に重みが出てきます。 ソフトウェアの分野では「生産性の良い言語」みたいなものは割とよく議論されていて、C++などは C++11からC++20 に至るまで実に様々な言語拡張が図られています。Pythonなどのシェアが非常に広がってるのは周知の事実ですし、Rust や Go など様々な言語が様々な用途で非常に速いスピードで進化を遂げています。 FPGAにおいても、SystemVerilog であったり、HLS であったり様々な新しい言語や言語拡張が出てきていますので、これらをどう使っていくのかというところは重要な話には思います。

一方で、FPGAをハードウェアとして開発する場合においては、歴史的経緯からRTL記述ルールを欠陥保証に重点を置いて定めているケースもしばし見受けられ、機能価値側の生産性向上を阻害しているケースもあるように思います。

ソフトウェア再利用

「ソフトウェア再利用」で検索するといっぱい話が出てくる程度には奥深い話です。

どこで読んだのかは忘れましたが、「ソフトウェア部品を汎用的に使える部品にしようとすると3倍コストがかかる」なんて話があったように思います。実際はケースバイケースなので3倍とかはまあ適当な比喩表現なのだと思いますが、設計視点を一段上げて「一度独立性が高く、汎用的なスペックをちゃんと切った部品にしてから、個別にテストして結合する」というのは、「今作ってるものの事だけ考えて勢いで書いて、今の条件内だけテストする」のに比べると手間はかかるのだと思います。

ソフトウェア開発の中では1度しか使わないものと、長らくメンテしたり再利用するものがありますので、長期視点に立った時の生産性は重要です。

RTLのソースでも、汎用的な機能なのに特定システム固有の信号名で、システム固有の機能が混ざっているモジュールなんかよく見かけますし、そういうものに限って、条件の違うところに移植して使うとバグがボロボロ出てきたりなんて話もよく聞きます。

一方で Xilinx のライブラリの中でも、parameter を変えるだけでいろんな用途にフィットできる部品なんかは沢山供給されています。 parameter が増えるほどに検証項目は増えているはずですが、仮に工数が3倍かかっても、3回以上再利用すれば元が取れるわけで、特にFPGAの得意とする「少量多品種」の市場では「どの部分を再利用可能に作るべきか?」という問題はソフトウェア同様に重要に思います。

ソフトウェア見積り技法

これもまた永遠の課題ですね。ここに関してはハードウェアとしてみたFPGA開発の方に分があるかもしれません。

それでもやはり工数や使用リソース量など見積もりの難しさはハードウェアもソフトウェアもどちらも一筋縄ではいかないものではないでしょうか?

ソフトウェアもファンクションポイント法に始まって、ほんとうにいろいろな見積もり技法が研究されていますが、結局「今まで世になかったものを初めて作る」ケースにおいては、結局は経験則から置いた値を元に組み上げていくことになる気はします。

ソフトウェアテスト技法

これは間違いなくそのままFPGAでも通用すると思います。ソフトウェアテストには様々な技法が存在しています(そしてそのうちの結構多くはハードウェアから来たものも多いと思います)。

などなど、この辺の有用性はハードウェアもソフトウェアもあまり変わらないと思います。

その中で、FPGA開発は

  • モジュール単位でポートの入出力のみで外部仕様が閉じている
  • モジュール内でOSのAPI呼んだりなどの環境に影響されない
  • 割り込みとかスレッド競合とか外因で乱されない

と、メリットだらけなのでかなり理想通りのテストができるように思います。

ソフトウェア構成管理技法

github とか gitlab みたいなもの使いましょう。 これはもうソフトもハードも無いですね。

ソフトウェア進捗管理技法

これについては、見積もりに直結する話なのですがソフトウェアよりカオスな工学分野ってあるのかなと思うぐらい、信用できない世界かもしれません(最後の10%に工程の半分が費やされるとか)。

FPGA開発もちゃんと同じ領域に足は踏み込んでいると思いますが、RedMine のようなソフトウェアの数々のツールは活用して、進捗管理、課題管理、バグ管理のようなことは従来のソフトウェア同様にできると思います。

プログラミング技法

SystemVerilog や HLS を持ち出すまでもなく、VerilogVHDL などの言語で十分チューリング完全な言語です。 AXIなどの共通インターフェースを備えたモジュールを定義して、インスタンスを作って、繋いでいくというのは、オブジェクト指向です。

OpenCL, CUDA, GLSL, OpenMP, MPI などの一般的な並列プログラミングに対して、RTL記述はむしろ簡単なくらいと思います。

時間方向に関して、CPU上のプログラムは計算時間がどれくらいか定まらない(いつ割り込みが来たり、キャッシュミスしたり、分岐予測ミスしたり、不確定要素山盛り)のに対して、RTL記述は極めて単純です。RTLを使うだけで RealTimeOS なんか持ってこなくてもリアルタイム保証が可能です。 GPIOを相手にしたI/Oプログラミングも時間厳密なので楽々書けてしまいます。

私としては従来のプログラミングパラダイムの幅が広すぎて、今更RTLを加えたからと言って特に新しい要素は無いと思っていますし、むしろ単純な部類ではないかと思っていたりもします。

おわりに

以上思いつくがままにいろいろ書いてしまいましたが、まあ、ブログの駄文なので許してください。 結論としては、私としては「FPGAはどこまでもソフトウェアだ」という事です。

こうして書いてみるとFPGA開発をソフトウェア開発として考えるなら考えるで、ちゃんとソフトウェア工学しないといけないのかなともあらためて再認識した次第です。

少なからず、「ある程度完全性のある回路を単位としたハードウェア」として使われていたデバイスを、「銀の弾丸が存在しない」土俵で活用しようという話なので、同じデバイスを使っているスタンスの違う人同士で歩み寄る際には少なからぬ壁はあるのだろうなとは思っております。