$30 off During Our Annual Pro Sale. View Details »

実践的!FPGA開発セミナーvol.16 / FPGA_seminar_16_fixstars...

実践的!FPGA開発セミナーvol.16 / FPGA_seminar_16_fixstars_corporation_20221124

2022年11月24日に開催した、「実践的!FPGA開発セミナーvol.16」の当日資料です。

More Decks by 株式会社フィックスターズ

Other Decks in Technology

Transcript

  1. Copyright© Fixstars Group Who I am Yoshitaka TAKEMOTO 竹本 義孝

    ソリューション第四事業部 シニアエンジニア
  2. Copyright© Fixstars Group Verilog 開発の不満 • Verilog 言語の機能が低い ◦ System

    Verilog では assertion や interface やらいろいろ使える!! ▪ SV の機能が使えるかどうか割と環境依存 • C社 で使えた SV が I社 でコンパイルできなかった思い出 ▪ Verilog ならどこでも安定 • Verilog の開発支援環境が貧弱 ◦ 現在は LSP を開発されている方もおられます ▪ https://github.com/imc-trading/svlangserver ▪ https://github.com/dalance/svls ◦ VSCode 使いなんですけど、良い設定ないですかね • 論理は楽しいけど Verilog は何も楽しくない ◦ 個人の感想です。効果には個人差があります 5
  3. Copyright© Fixstars Group Chisel3 でゴリゴリ開発してみた話 • 最近 Vivado/Vitis HLS ばかりなので、クロック単位の論理を書きたかった

    ◦ 友人とちょっと FPGA 開発する話になりました(趣味) • しかしVerilog は書きたくない • System Verilog は環境ごとに何が使えるのか調べるの面倒くさい • でも Verilog は書きたくない そうだ、 Chisel 3 で開発すればいいじゃない というわけで、テストコード含めて1万行ぐらい ゴリゴリ書いてきた知見をお話しします 6
  4. Copyright© Fixstars Group Chisel とは • Verilog しんどいから作られた(たぶん) HDL を生成するための言語

    ◦ 言語というか、 Scala の 内部 DSL ◦ JavaScript でいう CoffeeScript とか TypeScript ▪ 他にも色々あるけど、RISC-V で使われているという実績がある • 公式サイト: https://www.chisel-lang.org/ ◦ GitHub: https://github.com/chipsalliance/chisel3 8
  5. Copyright© Fixstars Group Chisel のメリット • Scala なので IDE がリッチ

    • テストが書きやすい • Verilog を生成できるのでどの環境でも動く • Verilogでは面倒・難しいトリッキーな書き方が容易 ◦ 関数内でモジュールのインスタンス化 ◦ 関数内でFFの値を変更したり、論理を動的に生成したり ◦ モジュール間の接続の関数化 ◦ バルク接続が超便利 • DPI-C が無くてもプログラミングやライブラリの機能を強力に使える 9
  6. Copyright© Fixstars Group Chisel のデメリット • Scala であるためか重い ◦ Chisel3.6

    の CIRCT でどの程度早くなるのか次第 • テストが書きにくい • 出力された Verilog を人間が読むのは難しい ◦ Chisel で書いたモジュールを Chisel がコンパイルして生成した論理を Chisel でテスト… ◦ ところで Chisel には保障とかないですよね?お? ▪ A 社とか C 社とか I 社のツールにバグがないってわけでもないけど • メタな書き方してると割とバグ(?)を踏み抜いて悩む ◦ implicite やら AST が多すぎて自分のコードがバグってるのか、 Chisel がバグってるのかも分からないこと が割とある • 間違えたときのエラーが不親切 ◦ C++のメタプログラミングの様なエラーは勘弁してほしい ◦ 何も言わずに轟沈する V よりはマシと言えなくもない • negative reset が欲しい。切実に欲しい。 10
  7. Copyright© Fixstars Group Chisel の開発環境 Scala が開発できれば環境は何でもOK • 私の開発環境 ◦

    OS: Ubuntu 20.04 ▪ シミュレーションに Verilator を使う場合は WSL か Linux が必要 • WSL2でも FPGA の書き込みに USB を使うのが正直面倒くさいので Ubuntu マシン用意する方が楽 • FIRRTL で済ませる場合は不要 (ちょっと巨大なロジックになってくると遅い) ◦ JDK: Java 8 (apt で入れたんだったかな?) ◦ sbt: 1.7.0 (apt で入れたんだったかな?) ▪ Scala: 2.13.8 ◦ エディタ: VSCode ▪ Metals: https://scalameta.org/metals/docs/editors/vscode 一昔前は IntelliJ しか Scala の開発環境はなかったが 現在はVSCode で大きな不満はなく開発可能 ※個人の感想であり、効果・効能を保証するものではありません 12
  8. Copyright© Fixstars Group Chisel のディレクトリ構成 通常は Chisel 専用のプロジェクトを作るのが筋 でも面倒くさい EDA

    用のファイルなども一括したディレクトリ構成は以下の落ち着きました 13
  9. Copyright© Fixstars Group Chisel プロジェクトの初期化 build.sbt を作成してプロジェクトの初期化(Metals 任せ) • build.sbt

    は以下を参考に作成(ルートディレクトリが異なる程度) • https://github.com/freechipsproject/chisel-template/blob/main/build.sbt 15 保存してこのようなポップアップが出たら、 Import build を押せばOK
  10. Copyright© Fixstars Group Chisel のサンプルを作ってみる 16 package sample import chisel3._

    import chisel3.util._ class Sample extends Module { val io = IO(new Bundle { val in = Input(Bool()) val out = Output(Bool()) }) val reg = RegInit(false.B) reg := io.in io.out := reg }
  11. Copyright© Fixstars Group Chisel から Verilog へ Sample.scala に以下を追加 17

    object Sample extends App { val dir = "rtl/chisel" // どんなオプションがあるか知りたければ、 // 最初に "--help" を入れて実行する val option = Array( // "--help", "-td=" + dir, // 出力ディレクトリの設定 "--emission-options=disableMemRandomization,disableRegisterRandomization" ) (new chisel3.stage.ChiselStage).emitVerilog( new Sample, option ) }
  12. Copyright© Fixstars Group Chisel から Verilog へ 18 run で実行

    デフォルトでは chisel ディレクトリのプロジェクトが選択されていないので 「project chisel」で選択 ターミナルを開き、 sbt を実行する sbt は起動が遅いので、ターミナルを占有して立ち上げっぱなしにしておく ※ ワンライナーで実行する場合は 「 sbt "project chisel" run 」
  13. Copyright© Fixstars Group Chisel を非同期リセットにする 21 package sample import chisel3._

    import chisel3.util._ class Sample extends Module with RequireAsyncReset { val io = IO(new Bundle { val in = Input(Bool()) val out = Output(Bool()) }) val reg = RegInit(false.B) reg := io.in io.out := reg } ASIC な人でも実際安心
  14. Copyright© Fixstars Group Chisel と Verilog の簡易比較 22 Verilog Chisel

    数値 100 32’d0 65’h1FFFFFFFFFFFFFFFF true false 100.U(unsigned) / 100.S (signed) 0.U(32.W) / 0.S(32.W) “h1FFFFFFFFFFFFFFFF”.U(65.W) true.B false.B FF logic ff; always_ff @(posedge clk) if (!rst) ff <= 1’b0; else ff <= 1’b1; val ff = RegInit(0.U(1.W)) ff := 1.U(1.W) 三項演算子 c? a : b Mux(c, a, b) if - else if - else if (cond1) begin end else if (cond2) begin end else begin end when(cond1) { }.elsewhen(cond2) { }.otherwise { } 比較演算子 a == b a != b a === b a =/= b
  15. Copyright© Fixstars Group Chisel と Verilog の簡易比較 23 Verilog Chisel

    port 宣言 module X ( input [1:0] a, output [2:0] b ); val io = IO( new Bundle { val a = Input(UInt(2.W)) val b = Output(UInt(3.W)) }) 三項演算子連打 logic x; assign x = c1 ? a1: c2 ? a2: c3 ? a3: x_default; val x = WireInit( xDefault ) when(c1) { x := a1 } when(c2) { x := a2 } when(c3) { x := a3 } MuxCaseというのもあるにはある switch 文 case (state) X: endcase when().elsewhen().otherwise が良い MuxLookupやswitch-is があるにはあるが… instance 化 my_module i1 ( .x(x), .y(y) ); val i1 = Module(new MyModule) i1.io.x := x i1.io.y := y
  16. Copyright© Fixstars Group Chisel と Verilog の簡易比較 24 Verilog Chisel

    結合 assign x = {a, b, c}; x := Cat(a, b, c) bit 取得 if (x[1]) begin end when( x(1) ) { } [msb: lsb] x[3: 1] x(3, 1) 2次元配列 logic [7:0] array[0: 99] val array = Vec(100, UInt(8.W)) 1要素の長さが異なる配 列の定義とアクセス 簡単にはできない …と思う Scala の Seq と for を使って割と簡単に記述できる val array = Seq(Wire(UInt(8.W)), Wire(UInt(16.W),... for((w, i) <- array.zipWithIndex ) { when( logicIndex === i.U ) { value := w } }
  17. Copyright© Fixstars Group Chisel の Bundle 今まで何度か出てきた Bundle は SystemVerilog

    の interface の様なものです 25 interface X; logic [7:0] a; logic b; endinterface class X extends Bundle { val a = UInt(8.W) val b = Bool() } new Bundle { val a = UInt(8.W) val b = Bool() } SystemVerilog Chisel X という名前を付けずにインスタンスを作成する場合
  18. Copyright© Fixstars Group Chisel の Bundle 今まで何度か出てきた Bundle は SystemVerilog

    の interface の様なものです 26 interface X; logic [7:0] a; logic b; //※ modport で宣言しなくても使える modport o ( output a, output b ); modport i ( input a, input b ); endinterface class X extends Bundle { val a = UInt(8.W) val b = Bool() } // IO として使う時 val io = IO( new Bundle { val o = Output(new X) val i = Input(new X) }) SystemVerilog Chisel
  19. Copyright© Fixstars Group Chisel の Bundle 今まで何度か出てきた Bundle は SystemVerilog

    の interface の様なものです 27 interface X; logic [7:0] a; logic b; modport main ( output a, input b ); modport secondary ( input a, output b ); endinterface class X extends Bundle { val a = Output(UInt(8.W)) val b = Input(Bool()) } // IO として使う時 val io = IO( new Bundle { val main = new X val secondary = Flipped(new X) }) SystemVerilog Chisel
  20. Copyright© Fixstars Group Chisel の Bundle 今まで何度か出てきた Bundle は SystemVerilog

    の interface の様なものです 28 X x; ModuleA a ( .portX(x) ); ModuleB b ( .portX(x) ) val a = Module( new ModuleA ) val b = Module( new ModuleB ) a.io.portX <> b.io.portX SystemVerilog Chisel <> を バルク 接続演算子と呼びます。 := と違い、output/input をいい感じに繋いでくれま す Chisel では Bundle と バルク接続 をうまく利用して記述を圧縮することが基本
  21. Copyright© Fixstars Group Bundle間で バルク接続(2) 例: 他人が作った Bundle と自分の Bundle

    が実質同じなので接続したい 例: ValidIO と AXI-Stream とか 32
  22. Copyright© Fixstars Group Bundle間で バルク接続(2) DataView で Xbundle と YBundle

    のフィールド対応を定義し、 viewAs で変換 34 詳細は https://www.chisel-lang.org/chisel3/docs/cookbooks/dataview.html 参 照
  23. Copyright© Fixstars Group Chisel の基本 まとめ • 開発環境 ◦ OS

    は Linux の実機がお勧め ◦ エディタは VSCode で十分 • ディレクトリ構成 ◦ EDA ツールと一緒に開発する場合の私の構成について(基本からは外れている) • Chisel の初期化 ◦ build.sbt を書いたら後は Metals や sbt にお任せ • シンプルなデザインの作成と Verilog への変換方法 ◦ 非同期リセットの作り方もついでに紹介 • Chisel と Verilog で大きく違う基本的な構文についての比較 • Chisel の Bundle に関する基本項目 ◦ Chisel の Bundle はおおよそ SystemVerilog の interface ◦ Chisel のバルク接続は強力 ◦ おまけ:supertype が実装されるらしいよ • Chisel の列挙型について 37
  24. Copyright© Fixstars Group Chisel でテストを作る 波形を取得する為に 「testOnly * – -DwriteVcd=1」を実行

    コマンドの意味は、全てのテスト実行する(* のワイルドカード)。 オプションとしてwriteVcd=1(波形ファイルの書き出し)を渡す ということ 45 test_run_dirに 「〇_should_•」ディレクトリがあり その中に vcd ファイルが保存される GTKWave などで波形を確認
  25. Copyright© Fixstars Group Chisel のテストを Verilator で実行 論路規模が大きくなってくると、 FIRRTL のシミュレーションでは時間がかかりすぎて待っ

    てられない 時間がかかるな、と思ったら Verilator でシミュレーションすることを検討すると良い .withAnnotations(Seq(VerilatorBackendAnnotation)) 49 Verilator のコンパイルに時間はかかるけど、 シミュレーションは非常に早い
  26. Copyright© Fixstars Group Verilator がおかしくなったら Verilator が成功するはずのテストで失敗することがある - FIRRTL でテストをすると成功する

    - ポート名などを変更しても VCD に反映されない Verilator の VCD 波形が出ないこともよくある sbt を閉じて、target (targetとchisel/target)とtest_run_dirを削除すると、うまくいく。 何が・どれが悪いのかはよくわからない。 50
  27. Copyright© Fixstars Group Chisel でテスト メリット • 書くのが簡単 ◦ shell

    script とか用意しなくても実行集計すぐできる ◦ 補完が効くのは偉大 • 外部のライブラリなどをそのまま使える ◦ CRC計算の結果があってるかとか、一度ファイルに出すとかせずにライブラリ呼び出した結 果を直接使える • Scala の強力な構文が色々使える ◦ for とか ◦ match とか 51
  28. Copyright© Fixstars Group Chisel でテスト デメリット • 書くのが辛い ◦ Verilog

    で言ってしまえば、テストベンチの initial 内で全部のテストを記述するようなもの ◦ always の様な時間の並列化や、 @(posedge 信号) みたいな記述が簡単にできない ▪ 時間の分岐: fork{}.join() で分岐 ▪ 毎クロックチェック: assert ◦ 内部の信号に簡単にアクセスできない • マルチ ドメイン クロックのテストが辛い ◦ RTL 側は withClock で CDC は割と簡単に書ける ◦ テスト側はテストベンチのクロック単位でしか時間が進まないので CDC が書けない ▪ 私はテストベンチ用 モジュールでカウンタを使ってクロックを作るようなやり方で記述した • it should “” の単位でテストを実行できない ◦ tag というのを使えばなんかできるみたいだけど ◦ scala 力が足りないだけ?よくわからない • 入力がクロックの立ち下がりに同期してるのが辛い ◦ 信号が増えると目がバグるのでエッジをそろえないでほしい… 52
  29. Copyright© Fixstars Group Chisel でテスト まとめ • Chisel でテストする方法について ◦

    基本的には poke で値を突っ込んで expect で確認 ▪ peek〇 で値として読みだすこともできます ◦ assert を使えば毎クロック勝手にチェック可能 • Chisel のテストを Verilator で走らせる方法について ◦ VerilatorBackendAnnotation をつける ◦ よく変になるので target ディレクトリとtest_run_dir を削除して sbt 再起動 • Chisel のメリット ・ デメリット ◦ 割とテスト書くのしんどい 53
  30. Copyright© Fixstars Group 論理どうやって設計してる? • VSCode + Markdown + mermaid

    + Draw.io + タイミングチャート清書サービス(改造) 55
  31. Copyright© Fixstars Group 論理どうやって設計してる? • VSCode ◦ 昨今独り勝ち状態のエディタ。Atomさん… • Markdown

    ◦ いわずもがな • mermaid ◦ 状態遷移図作成等に利用 ◦ GitHub で Markdown に埋め込んでそのまま表示できる ◦ VSCode には Markdown Preview Mermaid Support を導入すれば Markdown に組み込める ▪ https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid • Draw.io ◦ HTML5/JavaScript で作られた Visio みたいなもの ◦ VSCode では Draw.io Integration で VSCode 上で使うことができる ▪ https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio ◦ *.drawio.svg という拡張子にして保存すれば、Markdown に組み込めて、Draw.io で編集できるので便利 56
  32. Copyright© Fixstars Group 論理どうやって設計してる? • WaveDrom ◦ https://wavedrom.com/editor.html ◦ 美しいタイミング図が作れる

    ◦ 最近はこれが使われていることが多い印象 ▪ 正直タイミング図を書くならこれ一択 ▪ GitHub 対応してくれないかな… でも書くの面倒くさい ※個人の感想です。用法容量を守って正しくお使いください 57
  33. Copyright© Fixstars Group 論理どうやって設計してる? • タイミングチャート清書サービス(改造) ◦ こんな感じに2カラム化して出力ファイル名を変えれるようにしてる ◦ SVG

    の先頭にオリジナルデータが格納されてるので復元できるようにしてる ◦ SVG なので Markdown でそのまま表示できる。便利 ◦ 信号名が調整しないと見切れるのは如何なものか… ▪ タイミグチャート清書サービス記法→WaveDrom→SVG の仕組みを作ろうと思い早や幾年 59
  34. Copyright© Fixstars Group Chisel と コンストラクタ と フィールド • Chisel

    でロジックを書くこの部分はコンストラクタ • ここにモジュールや信号なども定義していくのがチュートリアル的なスタイル ◦ 定義した信号などはフィールドとなり外部からアクセス可能 • io.portName の様に毎回 io. を書くのが面倒になってくる ◦ val portName = io.portName として横着することを覚えた 64
  35. Copyright© Fixstars Group Chisel と コンストラクタ と フィールド • 極力

    private val にするようにした • private をつけるのも面倒になって {} でくくるようになった 67
  36. Copyright© Fixstars Group Chisel と IO Bundle チュートリアルでは、入出力が反転するポートは Flipped を使って書かれる

    Stream の様に入出力がはっきりしてる Bundle なら覚えやすいが、 複雑な Bundle になってくるとどちらで反転するのかわからなくなる 68 val primary = new HogeBundle val secondary = Flipped(new HogeBundle)
  37. Copyright© Fixstars Group Chisel と IO Bundle 結局 SystemVerilog の

    modport をまねる形に落ち着いた 69 class HogeBundle extends Bundle { val moge = Output(略) val piyo = Input(略) } object HogeBundle { def apply() = new HogeBundle def ctrl = new HogeBundle def func = Flipped(new HogeBundle) } val ctrl = HogeBundle.ctrl val func = HogeBundle.func
  38. Copyright© Fixstars Group Chisel ノウハウ まとめ • FFの作り方 ◦ RegNextPair

    という object を作って使ってます • 内部信号にアクセスする悲劇 ◦ private val を使いましょう ◦ 面倒なら { } で囲いましょう • IO Bundle の Flipped ◦ 結局 SystemVerilog の modport は良いスタイルだと思う 70
  39. Copyright© Fixstars Group Chisel は救いになるか。 • 個人的には Verilog よりもずっと好きだし、書いていて楽しい •

    趣味用途には今日からの使用をお勧めします • 仕事に使えるかどうかは、微妙 ◦ 万人が使える物ではない ▪ 非プログラマとプログラマで書きあがるコードに大きな差が確実に出る ◦ エラーがきつい ◦ 保証がないことにどう向き合うか? • 既存モジュール接続のためのグルーロジックとしては仕事に使える ◦ 読める程度の Verilog コードしか出てこないなら問題は何もない • 小さなロジックで社外に出ないコードなら活用可能 72
  40. Copyright© Fixstars Group 最後に • Scala の資を容易に取り込めるのは強い ◦ 一方で、 Scala

    の上に構築されているが故の問題点があるのも事実 • メタ プログラミング的な話もしたかったけど、時間足りないので削った ◦ Vivado IP を生成する話も削った • 私が思う Chisel の最大の成果は FIRRTL ◦ そして時代は LLVM-CIRCT へ ◦ 今後もっと LLVM-CIRCT を介してトランスパイルする言語が増えると面白いですね • Chisel は今後も安泰? ◦ RISC-V の流れ的に十分安泰 ◦ 後はユーザー数の問題かと ◦ むろん、JavaScript で言う Chisel = CoffeeScript で今後 TypeScript が出てくる可能性も ▪ でも、 CoffeeScript は今でも俺たちの心の中で輝いてるよね? みんなぜひ Chisel を使ってみましょう! 73