Verilog Quiz の答え。bとcには次の値が入っていました。
まずは2番から。
// 2.
a = b + c;
$display("%b", a);
これは、2+3の結果がaに代入されて5、表示は
となります。(101)2=5 ですね。
ところが1番の場合、
// 1.
$display("%b", b + c);
表示は
となります。実は2番のとき正しく表示されたのは、左辺のaが8bit変数のため右辺の式も8bitにbit拡張されて、{6’h0, 2’h2} + {6’h0, 2’h3} として計算されていたからです。1番の場合、左辺がないので計算は2bitの範囲で行われて、5の場合3bit必要ですが上位1bitがなくなって01となったわけですね。重要なのは左辺のbit数によって右辺の計算に使用するbit数が決まるというところです。
では3番。左辺と右辺がある式ですね。
// 3.
a = {b + c};
$display("%b", a);
表示は
左辺は8bitなのに!! 実は、連接演算子を使用すると左辺のbit数によらず、連接演算子内の変数のbit数によってのみ計算のbit幅が決定します。このような式をSelf-determined expressionというようです。連接演算子内には2bit変数しかないので計算結果は01、aは8bit幅なので表示は8桁になったというわけです。
次は、5番。
// 5.
a = 8'h01 << (2 + 3);
$display("%b", a);
1を5bit分左シフトしているので、表示は
となりますね。
じゃあ4番はどうなるでしょう。
// 4.
a = 8'h01 << (b + c);
$display("%b", a);
予想が付くかもしれませんが、<<演算子の右側もSelf-determinedになります。つまり他の式に影響されずbit幅が決定するので、2bit幅+2bit幅になり2+3=(01)2。1bit左シフトになるので表示は
となります。
Self-determinedやこの事項については、IEEE Std. 1364-2005 「5.4 Expression bit lengths」に書いてあります。むずかしい!
Cの場合はどうなるんだろうと書いたけど、一般的には1バイトの変数も内部では32bit分メモリを消費していたりするよね? 計算も32bitでおこなって、代入先が32bit未満の場合、上位bitを破棄したものが入るって感じな動作になるのかな?