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

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

SystemC基本構文②

データ型から続きを。

データ型

基本的にsc_***。C++のデータ型であるbool, int, char, doubleも使用可能。代表的なデータ型は、

データ型 内容
sc_int<N> N bit符号付き32bit整数
sc_uint<N> N bit符号なし32bit整数
sc_bit '0','1'の2値
sc_logic '0','1','x',z'の4値
sc_bv<N> sc_bitのN bitベクタ型
sc_lv<N> sc_logicのN bitベクタ型
sc_fixed<NW, NI> 符号付き固定小数点数
sc_ufixed<NW, NI> 符号なし固定小数点数

sc_bvやsc_lvの使いどころについては、今後出てきた時に詳しく見ることにしよう。あと、多分ライブラリが切り出された状態で提供されているとか、そういう都合があるのだろうがbit精度を規定したアルゴリズムCでACデータライブラリを使用している例をよく見かける。これの違いもいずれ見ておきたい。

www.mentorg.co.jp

信号と変数の使い分けについて

sc_signalで宣言した信号はデルタ遅延を持ち、sc_signal型からのリードにはread()メソッド、代入にはwrite()メソッドもしくは代入文(=)を使用する。sc_signalはVerilogでいうノンブロッキング代入になるということだろう。

sc_signal< sc_uint<8> > indata, outdata;
sc_uint<8> data, outvar;

data = indata.read();
outvar = data + 1;
outdata.write(outvar); // outdata = outvar;でも可

sc_signalがノンブロッキング代入になるのに対して、変数はブロッキング代入となり順序的に実行される。変数のほうがシミュレーションが速いので、プロセス内部の手続きには変数を使用するのが一般的。 プロセス内のローカル変数はデフォルトでauto(毎回初期化される)、初期化したくない場合はstatic、定数扱いはconst。この辺は普通のCと同じ。

イベントとwait()文

イベント

  • イベントは信号の変化を意味する
  • プロセス宣言時にsensitive << で指定するセンシティビティは静的なセンシティビティという
  • bool型の場合、0→1の変化を示すpos()、1→0の変化を示すneg()が使用可能

wait()

  • イベントが発生するとwait()までの記述を実行してプロセス停止、次のイベント発生を待つ
  • 高位合成では、wait()のタイミングでデータをレジスタに保持することを意味する

wait()の記述例:

wait();         // 1[cycle]待つ
wait(n);        // n[cycle]待つ。SC_CTHREADのみ有効
wait(a0|a1);    // a0もしくはa1が変化するまで待つ
wait(a0&a1);    // a0とa1の両方が変化するまで待つ。同時変化でなくてよく、順序も不問
wait(n, SC_NS); // n[ns]待つ

wait_until

これは以前調査したように、SystemC2.3.3では廃止されている。

sc_eventとnotify()

  • イベント型sc_eventで宣言。notify()でイベントを起動
  • イベントの起動を受けるために、センシティビティリストでの指定もしくはwait(イベント名)
  • プロセス内部でwait(イベント名)に到達すると、その他のセンシティビティリストに記載された信号変化では先に進まない
    • 動的なセンシティビティというらしい
  • イベント型は実際の信号変化を伴わないため、高位合成不可。検証用
sc_event eventA;
eventA.notify();         // 即時通知
eventA.notify(1, SC_NS); // 1ns後に通知

wait(eventA);

単方向ハンドシェイキングと双方向ハンドシェイキング

  • 双方向ハンドシェイキングでは、receiverがreadyをアサート、senderがready=Hを観測してからvalidとともにデータを送出する
  • 単方向ハンドシェイキングでは、senderはreceiverの状態を観測せず、validとともにデータを送出する

f:id:samurai375:20200412201129j:plain