読者です 読者をやめる 読者になる 読者になる

SystemC: 連結の落とし穴

SystemC Advent Calendar2012 の 11日目bool型を連結するのはやめましょうでした(リンク先は同一)。
下手をしたら本記事は12日目ということになるらしいですが、
それはリンク先の人が決定するので、細かいことは知りません
なりました。

本題。個人的に、連結の落とし穴と言えば別の方だったのでそれについての記事。
ただ、元記事は別の方向でちょっと興味を惹かれたので、まずはそちらを。
何に興味を惹かれたかと言うと、出力結果。
出力部分を引用させていただくと、

in = 0b011111010
out = 0b000000001

ここで、in,out は共に sc_uint<8> で、2進表現で出力しているわけですが、
ここで思ったこと、この表現9ビットじゃないか?ということ。
ちなみに、試しに sc_int<8> 型の変数tmpに上述のinと同じ0xfaを代入して、
2進表現させてやると、

tmp = 0b11111010

あれ?今度はちゃんと8ビット。。。
signed 変数ならば最上位が符号だからそのままのビット幅で出せるけど、 unsigned のときは1ビット追加して、最上位に0を付加して正の数だと明示すると。
親切な気もするのですが、あくまで8ビット変数なのでちょっと気持ち悪いです。

だらだら書いてきましたが、ようやく本題の落とし穴w
ただ、こちらは超簡単です(え?
元記事と同様にboolが関わりますが、とりえあず下記のコードをどうぞ。

#include <systemc.h>

int sc_main(int argc, char **argv)
{
    sc_uint<8> out1, out2, out3;
    sc_uint<5> in1;
    unsigned int int_five;
    sc_uint<3> sc_five;

    in1 = 0x15;
    int_five = 5;
    sc_five = 5;

    out1 = (in1, 5);
    out2 = (in1, int_five);
    out3 = (in1, sc_five);

    cout << "in1 : " << in1.to_string(SC_BIN) << endl;
    cout << "in1,5 : " << out1.to_string(SC_BIN) << endl;
    cout << "in1,int_five : " << out2.to_string(SC_BIN) << endl;
    cout << "in1,sc_five : " << out3.to_string(SC_BIN) << endl;

    return 0;
}

出力は次のようになる

in1 : 0b010101
in1,5 : 0b000101011
in1,int_five : 0b000101011
in1,sc_five : 0b010101101

まず、in1の出力は初期値通りなので問題なし。
問題というかハマることがあるのが真ん中の2つ。
5という値を連結するため、
4つ目の出力の0b010101101が2,3番目にも出そう(と思わないですか?)ですが、
実際のところは、"5"やint_fiveは1ビット変数として連結される。
冷静に考えると、ビット幅の定まっていないものを連結しようとしているのだから、
こうなるのもわかるのですが、ハマるときはハマると思います。