« 4.3 Variations on a Scheme -- Nondeterministic Computing | Main | 今日の日記 »

2007.09.13

Verilogをはじめよう!

今日は、嘘、おおげさ、紛らわしいがいつもより多めです。

世の中にはHDLと呼ばれる言語があります。
まじめな説明はwikipedia http://ja.wikipedia.org/wiki/ハードウェア記述言語 をみてください。

HDLはいくつか種類があったのですが、今はAdaの血を引くVHDLと、C-likeなVerilog HDLの2つが生き残りました。HDLの特徴として、言語規格で決まっているのに、コンパイルできないという不合理があります。規格を満足するC++のコンパイラが無いとか、そんなレベルではありません。まずfor文が使えません。HDLが登場したときの初期の入門書には、これ見よがしにfor文とかが書いてあるため、調子に乗ってfor文を使うとコンパイラに怒られて涙したものです。基本的な制御構造であるforですらそうですから、後は推して知るべしです。一応whileとかuntilとか一通りの制御構造はありますが、基本的にループは使えません。

VHDLはAdaの血を引いているため、いちいち無駄に厳しいです。バイナリの"0100"を整数の4として扱うには、わざわざCONV_INTEGER()を使わないといけません。VHDLを書くような人間は、"0100"と4は同じ物として考えているのに、いちいち変換しないといけないのはとても苦痛です。最近は随分とましになったようですが、ソースの先頭にいっぱいおまじないを書かないといけないのは残っているようです。

VerilogはVHDLにくらべると随分ルーズです。僕はVerilogが好きなので、Verilogの他の言語と違うところを書いてみます。

まずはソースをみてください。

always @(posedge clk) begin
 if(a == b) begin
  a <= b * c;
 end else begin
  a <= a + b;
 end
end

C言語のようなPascalのようなそんな感じですが、1行目を除けば経験のあるプログラマならだいたい意味が分かるのではないでしょうか。aとbが同じなら、b * cをaに代入、そうでないなら a + bをaに代入します。たいして意味のあるコードではありません。

さて、ここで質問です。
このソースに出てくる演算子+は何をする演算子でしょうか?

a と bの和を求める演算子?

いいえ違います。これは、aとbのリアルな加算器(adder)を作る演算子です。HDLは演算子によって対応する回路が作られます。
上のソースをもう少し詳しく書くとこうなります。

これをコンパイル(合成)するとこうなります。

それっぽく、加算器、乗算器、比較器が作られているのがわかります。真ん中の並んでいる四角はif文で、右上のFDと書かれているのが変数aを入れるためのレジスタです。Verilogにおける演算子は、和を求めるわけでもなく、マシン語のaddに変換されるわけでもなく、前置、中置の違いはありますがλ式のような○○器を作る役割を持ちます。Paul Graham ならきっとこう言うでしょう。「加算器を生成するプログラムだって? いつそんなものが必要なんだ? そんなこと滅多にないよ、とほげプログラマは言うだろう。 いつでもさ、とVerilogプログラマは言うだろう。」

ここまで読まれた方は既に理解できていると思いますが、Verilogを使うことで想像しうるどんな命令セットでも作ることができます。
整数aとbを与えたら、1命令で和差積を同時に求めて、それぞれ別々のレジスタに入れることが出来ます。割り算もできそうですが、おそらく/はサポートされていません。試しにb * cをb / cに変えてコンパイルしてみると、こんなエラーがでます。

ERROR:Xst:870 - "../test.v" line 15: Can not simplify operator DIV.

Fuckin
割り算は難しいんですよ。Z80だって割り算が無かったでしょ。ほら、マシン語の知識はここでも役に立つ。まじめに割り算を実装したい人は、ベテランエンジニアに聞くか、パタヘネ本を読みましょう。そして、四則演算が普通にできる処理系にあらためて感謝しましょう。

乗算の結果がオーバーフローしたら全ビットが反転するような、やけくそな命令も作れます。偶数番地はライトスルー、奇数番地はライトバックのような、変態的キャッシュも頑張れば作れます。32/64bitのレジスタから解放され、RGB 10bitずつそれぞれ乗算したり、マスクしたりするような処理はよく使われますが、役に立つ回路を紹介するのはこの記事の意図するところでは無いので省略します。

省略したら書くことが無くなったので、今日はここまで。

|

« 4.3 Variations on a Scheme -- Nondeterministic Computing | Main | 今日の日記 »

Comments

The comments to this entry are closed.

TrackBack


Listed below are links to weblogs that reference Verilogをはじめよう!:

« 4.3 Variations on a Scheme -- Nondeterministic Computing | Main | 今日の日記 »