新しいHDL(ハードウェア記述言語): Veryl
はじめに
以下の記事に書いたとおり新しいハードウェア記述言語を作ることにしました。
1週間ほど作業したところでなんとなく動く感じになってきたのと、構文や機能のアイデアをメモしたり議論したりする場所が欲しいと思ったので、作りかけの状態ですが公開することにしました。
Veryl
新言語の名前は "Veryl" です。よくある宝石系プログラミング言語にならって「beryl(緑柱石) + VerilogのV = Veryl」となっています。ソースコードの拡張子は ".vl" です。
追加してほしい機能などがあれば Issue にてお願いします。自分の趣味的な部分もあるので必ず取り入れるわけではありませんが、なるべく検討します。
できること
現時点ではビルド済みバイナリの公開などはしていないので Rust がビルドできる環境で
$ cargo install veryl
$ cargo install veryl-ls # Language Serverを使う場合
としてください。
veryl
コマンドが各種処理を実行するコマンドです。
コマンド名だけで実行するとカレントディレクトリ以下の ".vl" ファイル全てを処理しますが、ファイル名を与えるとそのファイルだけを処理します。
veryl check
ソースコードのチェックをします。構文エラーだけでなく、意味的に間違っているものもチェックします。現時点では
- 数値リテラルにおける不正な数値(ex.
10'b3
) - 数値リテラルのビット幅あふれ(ex.
8'hffff
) - 不正な構文要素の使用(ex.
always_ff
以外でのif_reset
) - 識別子の重複
をチェックします。
veryl fmt
ソースコードをフォーマットします。特に警告なく上書きするのでご注意ください。
--check
オプションでフォーマットのチェックだけして差分を表示します。これはCIでのチェックなどを想定しています。
veryl build
SystemVerilogのソースコードを生成します。少なくとも構文的に正しいことは確認していますが、各種ツールで正常に受け付けられるかは未確認です。
Language Server
上記コマンドのうちチェックとフォーマットは Language Server からも実行可能です。チェックについては入力中にリアルタイムにチェックし表示されます。フォーマットは Laugnage Server のフォーマットコマンドに対応しています。
ソースコード例
現時点で処理可能なソースコードの例は以下になります。言語リファレンスなどはまだないので雰囲気で読んでください…。
vl ディレクトリ以下が Veryl のソースコードで、sv ディレクトリ以下がそれを変換した SystemVerilog のソースコードです。
またこのソースコードはフォーマッタの例にもなっていて、スペースやインデントなどを変更しても veryl fmt
をかけると必ずこの状態にフォーマットされます。
Discussion
素晴らしい言語をありがとうございます。とても興味深く見させていただいております。
少し要望等を書かせて頂いても良いでしょうか?(我儘ばかりで恐縮なのですが)
all-x, all-z
はあるようですが 'x や 'z も欲しいのですが難しいでしょうか?
ビット幅キャスト
ビット幅キャストとかは不要という考え方なのでしょうか? (個人的には欲しいです)
変換後の sv が verilator の lint に怒られがちな気がしています。
未定義変数
Verilog では未定義の変数が 1bit の wire になってしまうので、よく `default_nettype none 宣言するのですが、相当の機能があると嬉しいです。
属性の指定
FPGA開発で (* mark_debug="true" ) とか ( ram_style="block" *) などの指定を行いたいことがよくあるので、コメント同様にそのままSVにスルーしてもらえると嬉しいです。
ちなみにFPGAでメモリを推論させるのに
のような書き方をするのですが、veryl でも 可能でしょうか?
ご提案ありがとうございます。
1人で考えていると自分の使っている記述に関するアイデアしか出ないので、たくさん出していただけるのはとても助かります。
all-x, all-z
これは問題ありません。
(普段使わないので存在を忘れていました…)
ビット幅キャスト
ビット幅チェックはやりたいと思っています。
これから式の評価を実装するのでそのあとになる予定です。
キャスト方法や演算によるビット幅増加をどう扱うかなどはまだあまりイメージできていません。
未定義変数
当初やる予定だったのですが、SV側のパッケージを参照している場合など、疑似エラーが出そうだったのでいったん取りやめていました。
階層参照しない単体の識別子なら誤判定もしないと思うので限定して実装しようと思います。
属性の指定
もともと
ifdef
関連をRustのようにアトリビュートにしたいと思っていまして、それと一緒に解決できるかな、と思っています。みたいなイメージです。
(コメントは実は結構扱いが難しいので、できるだけ正式な構文要素としておきたいです)
ありがとうございます。いろいろと理解できました(勉強になります)。
Veryl の段階でチェックできると一番嬉しいですね。ただ parameter の bit 幅が決まらないと判定できないところとかは残りそうな気もするので、変換後のSVも lint 通るように二重チェックしたくなる気もします。
これは有難いです。
たしかにアトリビュートの方が良い方法に思いました。
なるほど、勉強になります。
今後の進化がとても楽しみです。 よろしくお願いします。