Slide 1

Slide 1 text

RustでSystemVerilogパーサを 書いた話 dalance

Slide 2

Slide 2 text

自己紹介 ● 名前:初田 直也 ● Githubアカウント:dalance ● 所属:株式会社PEZY Computing ● 業務:プロセッサLSI開発 PEZY-SC2

Slide 3

Slide 3 text

目次 ● Rustとは ● SystemVerilogパーサを書く ● 出来たもの ● 今後の展開

Slide 4

Slide 4 text

Rustとは

Slide 5

Slide 5 text

プログラミング言語Rust(1/4) ● システムプログラミング言語 ○ C/C++と同じ領域 ■ Goと比較されることもあるが、それほど被ってない ○ GCやVMなし。ベアメタル環境でも使える ■ OS実装やUEFI実装あり ○ 組み込みプロセッサ対応 ■ ARM・RISC-Vの公式サポート ■ (当然非公式ですが) PEZY-SCもいける “rust-logo-512x512.png” by Mozilla is licensed under CC BY 4.0

Slide 6

Slide 6 text

プログラミング言語Rust(2/4) ● モダンな言語機能 ○ 基本は命令型プログラミング ○ 関数型言語由来の機能も取り込んでいる ■ 型クラス、型推論、式志向、イミュータブル ○ 独特のメモリ管理 ■ メモリ解放タイミングをコンパイル時に決定する ● GCがなくてもメモリは自動解放される ■ 決定できないコードを書くとコンパイラに怒られる ● いわゆる「ボローチェッカとの戦い」 “rust-logo-512x512.png” by Mozilla is licensed under CC BY 4.0

Slide 7

Slide 7 text

プログラミング言語Rust(3/4) ● 整備された公式ツール群 ○ コンパイラバージョン管理 ■ rustup ○ ビルドツール ■ cargo ○ ライブラリリポジトリ ■ crates.io ○ ドキュメントホスティング ■ docs.rs ○ リンタ・フォーマッタ・ Language Server ■ cargo-clippy/rustfmt/rls ○ テストフレームワーク “rust-logo-512x512.png” by Mozilla is licensed under CC BY 4.0

Slide 8

Slide 8 text

プログラミング言語Rust(4/4) ● ちょっと辛いライブラリ周り ○ 標準ライブラリは最小限 ○ デファクトスタンダードが決まってないものは選択が難しい ○ 非同期の言語仕様が fixしてないので非同期ライブラリが混乱してる ■ 年内にはなんとか ■ Webフレームワークとかは辛そう “rust-logo-512x512.png” by Mozilla is licensed under CC BY 4.0

Slide 9

Slide 9 text

業務でRustを使う ● みんなで触るコードに導入するのは難しい ○ 本業はASIC屋なので… ● 業務を効率化するツールをRustで書く ○ EDA絡みのニッチな需要を満たせる ○ 引き継ぎとか考慮しなくていい

Slide 10

Slide 10 text

作ったツール(1/2) ● amber ○ grep/sedの代替 ○ 巨大なネットリストを高速に検索するために作った ● procs ○ psの代替 ○ ライセンスを掴みっぱなしで暴走する EDAツールをスムーズに殺すため ● ptags ○ ctagsラッパー ○ ネットリストなどを無視して並列にタグ生成する

Slide 11

Slide 11 text

作ったツール(2/2) ● pipecolor ○ EDAツールのコンソール出力を色付けする ● git-skel ○ 複数プロジェクトでスクリプト類の同期を取る ● flexlint ○ 正規表現ベースのリントチェッカ ○ 今回はこれをSVパーサベースのものに置き換えるのが目標

Slide 12

Slide 12 text

SystemVerilogパーサを書く

Slide 13

Slide 13 text

用意するもの ● SystemVerilog言語仕様 ○ IEEE Std 1800-2017 ○ ユーザ登録すれば無料で手に入る ● パーサコンビネータライブラリ/パーサジェネレータ ○ 量が多いので手書きは厳しい ○ 今回はRustの型システムの恩恵を得たかったのでパーサコンビネータ ● 時間 ○ 量が多いので ○ 会社の業務に絡めて時間を捻出 ● 根気 ○ 量が

Slide 14

Slide 14 text

量が多いってどのくらい? ● BNF定義は仕様書のAnnex.Aにある ○ 全44ページ ○ BNF定義の数は1300弱

Slide 15

Slide 15 text

パーサを作っていく ● BNFを見ながらパーサコンビネータに落としていく ○ 型定義を厳密にしたかったので構文木の型定義も function_declaration ::= function [ lifetime ] function_body_declaration #[tracable_parser] #[packrat_parser] pub(crate) fn function_declaration(s: Span) -> IResult { let (s, a) = keyword("function")(s)?; let (s, b) = opt(lifetime)(s)?; let (s, c) = function_body_declaration(s)?; Ok((s, FunctionDeclaration { nodes: (a, b, c) })) } #[derive(Clone, Debug, PartialEq, Node)] pub struct FunctionDeclaration { pub nodes: (Keyword, Option, FunctionBodyDeclaration), }

Slide 16

Slide 16 text

作業量 ● 実装期間 ○ 約3か月 ● ソースコード ○ 全35000行 ○ 何度か全書き直しに近いことをしたので差分はかなり多い

Slide 17

Slide 17 text

言語仕様のミス?発見 ● パースできないサンプルソース多数 ○ Typo、括弧の対応漏れ ■ 一目で分かるものから、なんだかよく分からないものまで ○ Unicode記号 ■ “-”(ハイフン)と思いきや “–”(ENダッシュ: U+2013) ○ 通りそうなソースコードが BNFで受理できそうにない ■ パラメータオーバーライド付き classのstaticメソッド ■ [x: $]みたいなレンジアクセス ■ 階層付きのrandomize引数 ● Accelleraに報告を試みたが音信不通 ○ お金払ってないとダメなのか

Slide 18

Slide 18 text

出来たもの

Slide 19

Slide 19 text

sv-parser ● Rustのライブラリとして公開 ○ https://crates.io/crates/sv-parser ○ 中央サーバに登録されていて、 Rustプログラマなら簡単に組み込める

Slide 20

Slide 20 text

テストしてみた ● sv-tests ○ OSSなSystemVerilogツールのコンプライアンステスト ■ ターゲットはIcarusとかVerilatorとか ○ SystemVerilogのソースは色々なOSSプロジェクトから貰っている ■ 各ツールのテスト ■ RISC-Vコア ● sv-parserも追加してもらった

Slide 21

Slide 21 text

テスト結果 ● 今のところPass率トップらしい ○ パースしかしないので高めに出るというのはある

Slide 22

Slide 22 text

今後の展開

Slide 23

Slide 23 text

ライブラリを使ってツールを作る(1/2) ● リントチェッカ ○ https://github.com/dalance/svlint ○ 社内で使っている正規表現ベースのリントを置き換えた ■ 従来対応できなかったルール追加ができた ■ 正規表現のミスによるチェック漏れを発見 ■ メンテナンス性向上

Slide 24

Slide 24 text

ライブラリを使ってツールを作る(2/2) ● フォーマッタ ○ 次の目標 ○ リントよりはハードル高そう。マクロ絡みの扱いなど ● Language Server ○ VSCodeのSV拡張がいまいちらしい(伝聞) ○ Language Server実装にしてどのエディタでも使えるようにしたい