チラシの裏は意外と白くない

最近忘れっぽくなったので調べたことをチラシの裏に書きます

sc_in同士の演算

もう少し理解が進んだところで、全体における位置づけが明確になると期待して、気づいたことを書いておく。

以下の通り、入力信号in0, in1を加算して出力信号outにアサインするという単純なモデルを作ってみた。dont_initialize()がついていたりSC_METHODになっているが、ほかのモジュールを使いまわした以上の意味はない。

#ifndef __ADD_H__
#define __ADD_H__

#include <systemc.h>

SC_MODULE(add){
    //ports
    sc_in < bool >         clock;
    sc_in < sc_uint<32> >  in0;
    sc_in < sc_uint<32> >  in1;
    sc_out < sc_uint<32> > out;

    // member functions
    void method0();

    // constructor
    SC_CTOR(add) {
        SC_METHOD(method0);
        sensitive << in0 << in1;
        dont_initialize();
    }
};

#endif // __ADD_H__
#include "add.h"

void add::method0()
{
    out = in0 + in1;
    cout << "[method0] out = " << out << endl;
}

さて、この状態でコンパイルすると

$ make
add.cpp: メンバ関数 ‘void add::method0()’ 内:
add.cpp:5:15: エラー: no match for ‘operator+’ (operand types are ‘sc_core::sc_in<sc_dt::sc_uint<32> >’ and ‘sc_core::sc_in<sc_dt::sc_uint<32> >)
     out = in0 + in1;

のエラーが発生する。sc_inとsc_inの+演算が定義されていないということだろうか。

sc_inを直接計算してはいけない、のような規約があるのかもしれない。method0の中身を

  • sc_uint<32>型にキャストしてから加算
  • sc_uint<32>型の一時変数を介して加算

のどちらかをすればコンパイルが通り、所望の結果が得られた。

#include "add.h"

void add::method0()
{
    
    out = in0 + in1; // これはNG

    // sc_uint<32>型にキャスト
    out = (sc_uint<32>)in0 + (sc_uint<32>)in1;

    // sc_uint<32>型の一時変数を作って、これを介して演算
    sc_uint<32> in0_tmp;
    sc_uint<32> in1_tmp;
    in0_tmp = in0;
    in1_tmp = in1;
    out = in0_tmp + in1_tmp;

    cout << "[method0] out = " << out << endl;
}