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

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

SystemCで4bitカウンタを作ってみた③

前回はSC_THREAD、SC_CTHREADとsensitivityリスト周りを見た。今回は文法的なところを少し掘り下げてみる。

コンストラクタの記述に関して

sim結果は以下のどちらの書式を使っても同じだった。

#if 0
    SC_HAS_PROCESS( Counter4 );
    Counter4( sc_module_name );
#else
    SC_CTOR( Counter4 );
#endif

SC_HAS_PROCESSってあまり見ない記述だと思ったら、$SYSTEMC_HOME/include/sysc/kernel/sc_module.hにSC_HAS_PROCESS、SC_CTORの定義が記載されていた。

#define SC_CTOR(user_module_name)                                             \
    typedef user_module_name SC_CURRENT_USER_MODULE;                          \
    user_module_name( ::sc_core::sc_module_name )

// the SC_HAS_PROCESS macro call must be followed by a ;
#define SC_HAS_PROCESS(user_module_name)                                      \
    typedef user_module_name SC_CURRENT_USER_MODULE

ということで、どちらを利用してもよさそうだ。

sc_in_clkに関して

SC_MODULEのポート宣言でクロック信号を宣言する際にsc_inだったりsc_in_clkだったりするので、定義を確認したのが以下。場所は$SYSTEMC_HOME/include/sysc/communication/sc_clock_ports.h。

typedef sc_in<bool>    sc_in_clk;
typedef sc_inout<bool> sc_inout_clk;
typedef sc_out<bool>   sc_out_clk;

sc_inそのままだ。明示的にクロックであることを示すため、くらいに思っておけばよいかな。

sc_clockに関して

こちらはテストベンチの記述にあったほう。

    sc_clock                 clk( "clk", 10.0, SC_NS );

引数が異なるので、sc_inと同じ定義ってことはなさそうだ。$SYSTEMC_HOME/include/sysc/communication/sc_clock.hによると

    sc_clock( const char* name_,
              const sc_time& period_,
              double         duty_cycle_ = 0.5,                           // デフォルト引数
              const sc_time& start_time_ = SC_ZERO_TIME,   // デフォルト引数
              bool           posedge_first_ = true );                    // デフォルト引数

    sc_clock( const char* name_,
              double         period_v_,
              sc_time_unit   period_tu_,
              double         duty_cycle_ = 0.5 );                        // デフォルト引数

    sc_clock( const char* name_,
              double         period_v_,
              sc_time_unit   period_tu_,
              double         duty_cycle_,
              double         start_time_v_,
              sc_time_unit   start_time_tu_,
              bool           posedge_first_ = true );                   // デフォルト引数

3つの定義がある。C++の関数オーバーロードってやつだろう。同じ関数名でも呼び出し時の引数の数で挙動をかえられるやつ。上から引数の数は5個、4個、7個だが、テストベンチの記述で与えている引数の数は3個だ。C++をいまいち理解していないから厳しいが、どうやらデフォルト引数に関しては何も与えなくてもよい(そりゃそうか)ので、最低限与えるべき引数の数はそれぞれ2個、3個、6個となる。 実際の引数の数は3なので、1番or2番のどちらを呼び出しているか、どう判断しているのだろう。呼び出し時の引数の型チェックをして、今回のケースでは2番目の引数の型がdouble型だから2番目の定義(引数3+デフォルト引数1)だ、と判断しているのだろうか。まあ、引数の内容を見れば明らかに2番目の関数が呼ばれているんだろうけども。C++の内容なので、今回はあまり立ち入らないことにしょう。。

で、これを見ると"clk"という名前で周期は10、単位は[ns]、デューティー比はデフォルト引数として与えられる0.5ということになる。今後もこれ以外のパラメータをいじることはなさそうだし、デューティー比も多分変えることはないと思う。

sc_assertに関して

これは名前からしてだが、アサーション記述のようだ。テストベンチで

    sc_assert( counter4_i );

みたいに使われているので、正しくインスタンス出来たかどうかをチェックしているのだろう。とりあえず後回し。