なんとなく (System)Verilog に入門してみる。最初はどうにも生成される回路が想像できなかったが、Yosys で確認しながらいろいろ試して、だいぶもやが晴れた。
もともと論理合成目的のハードウェア記述言語として誕生したわけではないらしく、そういう視点からは言語仕様に不思議な部分がある。歴史的な事情として受けいれたほうがいいと思う。
reg 型でフリップフロップやラッチが生成されるとは限らない。これを決定しているのは、型ではなく always での使われ方である。フリップフロップやラッチを生成しない場合は wire 型、という使いわけは難しい。たとえば組合せ回路の記述に if, case, for, ... を使いたいとか、 function で一時的なラベルを使いたいときには reg 型を使う必要がある。
なぜこんなことになっているかというと、たとえば else clause のない if が書けて、その場合には前の状態を保存する必要があるからだ。SystemVerilog ではこのあたりが多少整理されている。
しかしこれ、フリップフロップを明示的に記述する形ではだめなのかな。
reg foo;
always @(posedge clk) foo <= bar ^ baz;
のかわりに
wire foo = d_ff(bar ^ baz, clk);
と回路がそのまま書ければ十分な気がしてしまう。
そもそも回路記述言語とそのメタ言語が分かれていてほしい。でもデバッグには便利なのかな。
function って常に module で置き換え可能ではないの?