SystemCの thread(process) を理解しよう

今回は、SystemCで記述する際に肝となるthread(process)の話です。
まずは、サンプルコードを見てください。

  • サンプルコード
#include <systemc.h>

SC_MODULE( hoge ){

  sc_in  <bool >        clk;
  sc_in  <bool >        xrst;
  sc_in  <sc_uint<32> > indata1;
  sc_in  <sc_uint<32> > indata2;
  sc_out <sc_uint<64> > outdata_met;
  sc_out <sc_uint<64> > outdata_thr;
  sc_out <sc_uint<64> > outdata_cth;

  void method_process();
  void thread_process();
  void cthread_process();

  SC_CTOR( hoge ):
    indata1("indata1")
    , indata2("indata2")
    , outdata_met("outdata_met")
    , outdata_thr("outdata_thr")
    , outdata_cth("outdata_cth")
  {

    SC_METHOD( method_process);
      sensitive << clk.pos();

    SC_THREAD( thread_process);
      sensitive << clk.pos();

    SC_CTHREAD( cthread_process, clk.pos() );
      reset_signal_is(xrst, false);
  }
};

void hoge::method_process(){
  if(!xrst) {
    outdata_met.write(0);
  } else {
    outdata_met.write(indata1.read() * indata2.read());
  }
}

void hoge::thread_process(){
  while (true) {
    if(!xrst) {
      outdata_thr.write(0);
    } else {
      outdata_thr.write(indata1.read() * indata2.read());
    }
    wait();
  }
}

void hoge::cthread_process(){
  outdata_cth.write(0);
  wait();

  while (true) {
    outdata_cth.write(indata1.read() * indata2.read());
    wait();
  }
}
  • 実行結果
    実行結果の波形はこのようになっていてすべて結果は同じです。

f:id:kocha2012:20121218052316p:plain

説明

SC_METHOD

  • 組み合わせ回路的なイメージ
  • プロセス関数内において、wait()を記述できない。
  • 関数コール後に再度イベント待ちになる。
    センシティビティリストに登録(ここではクロック立ち上がりエッジのみ)したイベント

SC_THREAD

  • タイミング制御が必要な回路イメージ
  • プロセス関数内において、wait()を記述できます。
  • プロセス関数から抜けると、再度呼び出されることはない。
    内部で whileやforなどで無限ループを構成することが多い。
  • 一部のツールでは高位合成対象外もある。

SC_CTHREAD

  • クロック制御が必要な回路イメージ
  • プロセス関数内において、wait()を記述できます。
  • プロセス関数から抜けると、再度呼び出されることはない。(SC_TREADと同じ)
  • リセット記述を分離出来る。
    記述を見てもらうと リセット部分が SC_CTHREADだけ違うと思います。
    記述の面でも見やすいかも。(個人差あります)

まとめ

SystemCでは 3つのプロセス関数を登録する方法があり、
それぞれの特徴を理解して記述することができます。

用途 wait コール回数
SC_METHOD 組み合わせ 不可 複数
SC_THREAD タイミング 1回
SC_CTHREAD クロック 1回


※シミュレーション開始前に一度実行されることや
 dont_initialize();については省略させていただきます。