まるさや

技術っぽいことかきます

SystemCのSC_CTHREADはメソッド抜けちゃいけないらしい


どうも,まるさです.

SystemCのSC_CTHREAD使っててちょっと詰んだので覚書




開発環境

Windows版Vivado HLS 2016.3を使って,SystemCを記述していました.

OSはWindows10です.







ちょっとした実験がしたかった

SystemCを使って次のようなハードウェアを書いていました.

  • データの入力をトリガに動く
  • 実行は一度だけ
  • valid信号を使って外部から入力を待つ必要があった

具体的には,次のような記述をしました.


SC_MODULE(sample)
{
  sc_in_clk   CLK;
  sc_in<bool> RST;
  sc_in<int>  din;
  sc_in<bool> din_valid;

  SC_CTOR(sample):
      CLK("CLK"),
      RST("RST"),
      din("din"),
      din_valid("din_valid")
  {
    SC_CTHREAD(thread, CLK.pos());
    reset_signal_is(RST, false);
  }

  void thread(){
    // dinが入るまで待つ
    while (din_valid.read()){
      wait();
    }

    // データを受け取る
    int data = din.read();
    /* やりたい処理 */

    wait();
  }
};


このコードだと,次のようなエラーがでました.


Found exit operation(s) (<上記コードthreadの2行目>) in the main loop of SC_CTHREAD 'sample::thread'.


exitしてねえし,と思いましたが,どうもSC_CTHREADSC_THREADで指定したメソッドは 終了してはいけないということのようです.

whileで無限ループを作るのが必須なので,while文に対してエラーがついてしまうということかな?







解決策

というわけで,threadのメソッドが終了しないようにすれば動くようになりました.


void thread(){
  bool flag = false;

  while (true){ // 無限ループにする
    if (!flag){ // 一度だけ実行されるようにするためのフラグ
      // dinが入るまで待つ
      while (din_valid.read()){
        wait();
      }

      // データを受け取る
      int data = din.read();
      /* やりたい処理 */

      flag = true;
    }

    wait();
  }
}







まちがった解決策

次のようなコードは,解決策とはなりませんでした.

最初と同じエラーが出てしまいます.


void thread(){
  // dinが入るまで待つ
  while (din_valid.read()){
    wait();
  }

  // データを受け取る
  int data = din.read();
  /* やりたい処理 */

  while (true) wait(); // 終了しないように無限ループ
}


メソッド直下のwhileが終了してはいけないようです.

ループを含まないような場合ならこれでもよいかもしれませんが, 今回はdinのためのビジーウェイトが入っているのでこのコードでは解決できませんでした.







それでは,

こんかいはこのへんで ノ


まるさ