Learn SystemC with Examples #3 (Event~Sensitivity)

Event

https://www.learnsystemc.com/basic/event

イベントとはsc_event型のオブジェクトであり、プロセス間の同期に使われる。
イベント通知が起こると、プロセスインスタンスはトリガーもしくはレジュームされる。

sc_eventは以下のメソッドを持つ。

  1. void notify(): 即時通知
  2. void notify(const sc_time&), void notify(double, sc_time_unit)
    • ゼロ時間: デルタ(遅延後の)通知
    • non-zero時間: 一定時間後の通知
  3. cancel()
    • 通知待ちのイベントを削除
    • 即時通知はキャンセルできない

制約

  1. sc_eventオブジェクトはエラボレーション時でもシミュレーション時でも生成できる。
  2. イベントはエラボレーション時でもシミュレーション時でも通知できる。ただし、エラボレーション中もしくはコールバック(before_end_of_elaboration, end_of_elaboration, start_of_simulation)内で即時通知をするのはエラーとなる。

イベントは2つ以上の待ち状態の通知をもつことはできない。

  1. もし通知待ち状態のイベントオブジェクトからnotify()関数が呼ばれた場合、最も早い通知時間のnotify()のみが生き残る。
  2. それ以外のスケジュール済み通知はキャンセルされる
  3. 即時通知はデルタ通知より優先され、デルタ通知はnon-zero時間後通知より優先される。この優先順は関数の呼び出し順とは関係ない。

Combined Events

https://www.learnsystemc.com/basic/event_combined
元記事が十分簡潔なのでここで特筆すべき点はない。

Delta Cycle

https://www.learnsystemc.com/basic/delta_cycle

いわゆるデルタ遅延に関する説明がされている。
(説明が面倒なので省略。VHDL, Verilogの本の方に詳しく説明されていると思う)
request_update(), update()関数のことにも触れられているがサンプルコードがないためここでは詳しい挙動がわからない。(Primitive Channelのチャプターで説明されてるっぽい)

Sensitivity

https://www.learnsystemc.com/basic/sensitivity

センシティビティとは、プロセスをレジュームしたりトリガーしたりするイベントもしくはタイムアウトの集合である。
センシティビティには静的と動的の2種類がある。

  1. 静的センシティビティ: エラボレーション中に固定される。モジュール内のそれぞれのプロセスのセンシティビティリストによって設定される。
  2. 動的センシティビティ: wait(), next_trigger() などによるもの

動的センシティビティと静的センシティビティの比較がサンプル中にある。
静的センシティビティは SC_THREAD直後に sensitive << e1 << e2; などのように書いて設定する。
感想:初めてこの文法を見たときは驚いた。正直今でも強い違和感を感じる。。。

SC_MODULE(SENSITIVITY) {
  sc_event e1, e2;
  SC_CTOR(SENSITIVITY) {
    SC_THREAD(catch_1or2_dyn);
  }
  void catch_1or2_dyn() {
    while (true) {
      wait(e1 | e2);
      std::cout << "Dynamic sensitivty: e1 or e2 @ " << sc_time_stamp() << std::endl;
    }
  }
};
SC_MODULE(SENSITIVITY) {
  sc_event e1, e2;
  SC_CTOR(SENSITIVITY) {
    SC_THREAD(catch_1or2_static);
    sensitive << e1 << e2;
  }
  void catch_1or2_static(void) {
    while (true) {
      wait();
      std::cout << "Static sensitivity: e1 or e2 @ " << sc_time_stamp() << std::endl;
    }
  }
};