Signal: read and write
https://www.learnsystemc.com/basic/signal_readwrite
sc_signalとは
- プリミティブチャネルであり、電気信号を運ぶワイヤーをモデリングするために使う
- evaluate-update方式を使う。これにより、同時read/writeのふるまいが一意になる。現在の値と新しい値を維持する。
- write() メソッドは現在の値と新しい値が異なるときにupdateリクエストを出す。
- sc_signal_inout_if<T> インタフェースがある。
コンストラクタ
- sc_signal()
- ベースクラスの sc_prim_channel(sc_gen_unique_name("signal")) 呼び出し
- sc_signal(const char* name_)
- ベースクラスの sc_prim_channel(name_) 呼び出し
- T& read() or operator const T& ()
- 現在の値の参照を返す。信号の状態を変化させない。
- void write(const T&)
- 次デルタ時刻に値を更新する。
- operator=
- write() と等価
- sc_event& default_event(), sc_event& value_changed_event()
- 値が変化したときのイベントの参照を返す。
- bool event()
- 同一シミュレーション時刻の直前のデルタ時刻のupdateフェーズでちょうど値の更新が行われた場合のみ true
sc_fifoとの比較
- sc_signal のスロット数は1
- sc_signal は現在の値と新しい値が異なる場合のみupdateリクエストをトリガーする
- sc_signal の read は値を削除しない。
executionフェーズ以外のsc_signalについて
- 初期値をエラボレーション中に書き込める
- sc_mainからエラボレーション中あるいはシミュレーション停止中に書き込める。sc_startの呼び出し前でも呼び出し後でも可能。
Signal: detect event
Signal: many writers
https://www.learnsystemc.com/basic/signal_many_writer
sc_signalのクラス定義
template <class T, sc_writer_policy WRITER_POLICY = SC_ONE_WRITER> class sc_signal: public sc_signal_inout_if<T>, public sc_prim_channel {}
- WRITER_POLICY == SC_ONE_WRITER の場合、複数のプロセスから信号が書き込まれるとエラー
- WRITER_POLICY == SC_MANY_WRITERS の場合、
- 複数のプロセスが同時に信号に書き込むとエラーになる
- 異なるデルタ時刻であれば異なるプロセスが書き込むことは可能
デフォルトはSC_ONE_WRITER。
読み込みは同一時刻か異なる時刻かにかかわらず複数のプロセスからread可能。
補注:
サンプルコード中、writer2() スレッドの s1.write(v); のコメントアウトを有効化すると以下のようにランタイムエラーになる。
信号s1に対して複数のドライバが存在するためである。
一方、s2に対する複数ドライバは SC_MANY_WRITERS 指定によりエラーにならない。
s2でも同時書き込みが発生するとエラーになるが、writer2内で同時書き込みが起こらないようデルタ遅延が挿入されているためエラーは起きない。
同時書き込みが起きてもエラーにならない別の機構については次のチャプターで紹介されている。
Error: (E115) sc_signal<T> cannot have more than one driver: signal `consumers.signal_0' (sc_signal) first driver `consumers.writer1' (sc_thread_process) second driver `consumers.writer2' (sc_thread_process) In file: ../../../src/sysc/communication/sc_signal.cpp:67 In process: consumers.writer2 @ 0 s
Resolved Signal
https://www.learnsystemc.com/basic/resolved_signal
Resolved signalとは、sc_signal_resolved 型あるいは sc_signal_rv 型のオブジェクトである。
sc_signal との違いは、resolved signalは複数のプロセスからの同時書き込みを許容し、チャネル内で衝突を解決する点である。
- sc_signal_resolved はプリミティブチャネルであり、sc_signalの派生クラスである。
- sc_signal_rv はリミティブチャネルであり、sc_signalの派生クラスである。
- sc_signal_rv は sc_signal_resolved と似ている。
- 違いはテンプレート引数。クラス定義は以下の通り。
- class sc_signal_resolved: public sc_signal<sc_dt::sc_logic,SC_MANY_WRITERS>
- template <int W> class sc_signal_rv: public sc_signal<sc_dt::sc_lv<W>,SC_MANY_WRITERS>
解決テーブルは以下の通り。補注:Verilogのwireと同じ。
| 0 | 1 | Z | X | 0 | 0 | X | 0 | X | 1 | X | 1 | 1 | X | Z | 0 | 1 | Z | X | X | X | X | X | X |
sc_signal<bool>
https://www.learnsystemc.com/basic/signal_bool
sc_signal_in_if<bool> と sc_signal_in_if<sc_dt::sc_logic>は追加のメンバ関数を持つ。
- posedge_event(), negedge_event()
- 値が変化し、新しい値が 1/0 の時にいつでも通知を出すイベントの参照を返す
- posedge(), negedge()
- 直前のデルタ時刻で値が更新され、新しい値が 1/0 の時にtrueを返し、そうでなければfalseを返す。
Buffer
https://www.learnsystemc.com/basic/buffer
sc_bufferはプリミティブチャネルであり、sc_signalの派生クラスである。
sc_signalとの違いはvalue-changed eventが値の書き込みが行われたときに発生する点である。
- sc_signal の場合、現在の値が1で1が書き込まれたとき、 イベントはトリガーされない。
- sc_buffer の場合、現在の値が1で1が書き込まれたとき、 イベントはトリガーされる。