yet another Scalaでデジタル回路を書く仕組み: Spinal HDL

2016年8月22日月曜日

先日あれこれと調べている時にSpinal HDLを見つけて気になったので、簡単に調べた結果をまとめておきます。今のところは主に自分用の備忘録というか下調べ状態です*1
[*1] そもそもyet anotherというのは3番手以降に出てきたものについて付けられる修飾子な気がしますね

Spinal HDLとは何か

Spinal HDLは、Dolu1990氏が中心となって開発している、ハードウェア(デジタル回路)設計用のScala組み込み言語(DSL)です。Gitのコミット履歴をみる限りでは2015/01/25に始まったものです*2
[*2] これに続く書き溜め分コミットの内容から、実際には2014年8月に開発を開始し、2015年1月に一旦の区切りまで到達したらしいことがわかります
ハードウェア記述言語(HDL)としての立ち位置はChisel HDLと似ています。いわゆる高位合成系ではなく、HaskellのLavaと近い位置付けのDSL+ライブラリ群です。

Spinal HDLとChisel(Chisel HDL)の関係

Chisel → Spinal HDL

登場順序でいうとSpinal HDLはChiselの後発プロジェクトです。ソースコード考古学的な意味ではChisel(Chisel HDL)の派生物にはあたらず、私が把握している限りでのコード共有はありません。Chiselに触発されて生まれた新実装です。
ライセンスも両者で異なります。Chiselは修正BSD(いわゆる3条項BSD)ライセンスです*3。Spinal HDLはコア部分がLGPL 3、周辺ライブラリがMITライセンスです。
[*3] 完全に蛇足ですが、Chiselを開発しているUC BerkeleyはBSD/修正BSDライセンスの本家本元でもあります
もともとDolu1990氏はChiselを使っていて、行き当たった問題などをissuesとしていくつか登録しています(#207, #213, #265)*4
[*4] issueコメントで2014年3月頃からChiselを学び始めたと書いています

ChiselとSpinal HDLの違い

Spinal HDLのドキュメントには「Chiselとどう違うのか?」について詳細に述べたページがあるので、参照してください。かいつまんで紹介すると、次のような問題を指摘しています。

Chiselはいくつか構文上の問題や下回りの実装に起因する実用上の窮屈さを持つ

  • プログラマがミスを犯しやすい局面で警告を出してくれないパターンがいくつかある
  • 標準で用意されているライブラリが物足りない
  • 生成されるVerilog HDLコードが到底人に読めるものではない
  • クロックドメインを複数持つ回路の実装が大変(リセット信号の扱いが中途半端、非同期リセットを持たないなど)
  • Scalaの型とChisel用の型を暗黙変換すべき
これらに対して、issueやPRという形でおこなわれた改善提案があまり実を結んでいないこと、Chiselプロジェクトの立ち上がりから経過した時間の長さを考えると今後も取り込まれる見込みが薄いことからSpinal HDLを開発するに至ったと記されています。

Spinal HDLの機能と仕様に関するメモ

あまりまとまっていませんが、構文面はChiselとキーワード差程度で似ていて、実際に使うと勝手が異なる雰囲気です。
  • 最終出力先のHDLとしてVerilog HDLだけではなくVHDLもサポートする
  • ChiselでModule クラスを拡張して回路を組むところでComponent クラスを拡張する
    • 出力先としてVHDLも選択できる事情によると考えられる
  • Bundleの扱いはChiselと似ている
    • 互換性のないBundle同士を<> でつなぐのはコンパイルか検証時に弾かれそう(未確認)
  • 論理回路を組んでいく部分は基本的にChiselと似た構文で書ける
    • 演算時のbit幅拡張仕様は異なる雰囲気(未確認)
  • 回路記述負荷を低減するための構文やライブラリがある程度存在する(後述)
  • ChiselのようなC++コード経由でシミュレータ(DUT)を生成してScalaコードとつないでテスト、の仕組みは持たない*5
[*5] Describe testbench from within Spinalで話題になっていますが、当面はRTL(コードの生成)側へ注力するようです。

Spinal HDLの良さそうな点(主観)

クロックとリセットの扱いが圧倒的にChiselよりもうまい

Spinal HDLは作者自身が前述のChiselに対する不満点で書いている、クロックとリセットの扱いに力を入れています。少なくともドキュメントを読む限りでは、これらは圧倒的にChiselよりも練られています。
  • 特にClockingArea という、モジュール(Component)の一部を指定クロックによって駆動する仕組みがクール
  • Chiselで最近ようやく導入に向かってる非同期リセットも当然のように存在する
  • クロックドメインまたぎで面倒なメタステーブル現象の回避のために、ChiselのAsyncFifo よりも扱いやすいバッファ(BufferCC )を用意している
詳しくはクロックドメインに関するドキュメントを参照してください。

ステートマシン構築の苦労を減らす仕組みを用意している

Spinal HDLが(Chiselと同様)高位合成系ではない以上、アルゴリズム記述のうえで問題になるのがロジックのステートマシンへの分解です。
Spinal HDLの標準ライブラリには、ステートマシン(FSM)を構築して状態間の遷移記述を省力化するライブラリが含まれています(ステートマシンの説明)。
ここでは以下の要素が登場します。
  • 状態開始時の処理: onEntry
  • 状態中の処理: whenIsActive
  • 状態を抜ける際の処理: onExit
これら3種類の処理と、状態間を遷移するためのgoto 呼び出しでロジックを構成します*6。ソフトウェア方面から来ると、キーワードを見た瞬間に「ヒッ、gotoだ!!」となるような気もしますが、つまりは必要悪です。
[*6] 2016/07/27のSFM: Added whenIsInactive.コミットで、なんとinactive時の処理も書けるようになりました。whenIsInactiveでステート間のgotoを発生させたらどうなってしまうのか…。
Chiselでenumを使ってシンプルな状態管理をしていくと、どうにもコードのネストが深くなりがちですが、この記法だとある程度コンパクトなコード群に分解できるのがメリットでしょうか。とはいえ、さすがに30-40ステートに及ぶものを書くならば諦めてC/C++からの高位合成系へ放り込んでBlackBox として組み込んだほうが良さそうですが。

せっせとComponentを切らなくともロジックの塊を記述できる仕組みがある

ロジックのまとまりを書いてローカルなスコープで利用したい場面は多いです。Spinal HDLでは、Componentを継承してio を定義せずともlightweightにロジック群を書く仕組みとしてArea を用意しています(Areaの説明)。
実はすでに紹介した指定クロックドメイン用ロジックを書くためのClockingAreaはこの一種です。
Chiselでインライン定義モジュールを作るためには内部でio変数を定義して入出力接続をおこなう必要があります。Chiselは設計上の判断としてこのような仕組みを用意していない印象ですが、クロージャにどっぷり浸かった民としてはやはり欲しいところです。

標準ライブラリに各種バスが揃っていて脳汁が出る

Spinal HDLのライブラリを覗いてみると、AMBA3(AHB-Lite、APB)、AMBA4(AXI4、AXI4-Lite)にAvalonMMもあります。実際に試してみないと性能のほどはわかりませんが、少なくとも既存のIPと指定バスでつないで実験をするあたりまでは省力で進められることを期待できます。

少人数プロジェクトゆえの小回りの効く開発

StateMachineの「泥臭いけど必要」な設計といい、Dolu1990氏が取捨選択を決定できる圧倒的な身軽さがある(そして精力的に開発している)ため進化速度がはやいです。なお弱点はそっくり裏返しで、アクティブ開発者がDolu1990氏含めて2名のみというところですね。

まとめ

Chiselインスパイア系言語/環境のSpinal HDLは、Chiselへの不満を解消するように多くの工夫を凝らして作られています。Spinal HDL環境には、Chiselにも欲しいなーと思うようなものがいくつも存在し、Chiselへ輸入できそうなものも多いです。
Spinal HDL→Chiselの輸入のためにChiselをforkするよりは大人しくSpinal HDLを使っても良いのかも、と感じるところもありました。しかし私がChiselの仕組みで特に気に入っているのがテスト周りで、この仕組みを現状のSpinal HDLは持たないので、すぐにこれを実用してみるイメージは湧いていません。
個人的にはNode.js対io.jsの構図で、Chiselの新仕様をせっせと練る場としてSpinal HDLが機能して、最終的に統合されるシナリオであると安心して両方を掘っていけるのですが、その実現には両者のユーザ規模が1万倍ぐらい足りませんね…。
今回書いたのは実用した評価レポートなどではないため、今後実際に触ってみて印象が変わる可能性も大いにあります。これからもたまにSpinal HDL事情を調べて、時折触ってみようと思います。

0 件のコメント:

コメントを投稿