SystemCのモジュール定義について(SC_MODULE)
モジュール構文
SystemCの基本的なモジュール定義はつぎのようになる。
C++があまりよくわからない人は、とりあえずこういうものなんだ、と思っておけばよいかと。
C++があまりよくわからない人は、とりあえずこういうものなんだ、と思っておけばよいかと。
#include <systemc.h>
SC_MODULE( ModuleName )
{
// ポート宣言(sc_port, sc_in, sc_out等)
// メンバ・チャネル(sc_signal, sc_buffer等)
// メンバ・データ(int, char, unsigned long等)
// プロセス・メソッド(プロセス)
// ヘルパ・メソッド
// コンストラクタ
SC_CTOR( ModuleName )
// : 初期化
{
// サブモジュールのインスタンス
// サブもジュールの信号接続
// プロセス登録
// 静的センシティビティ設定
// ユーザ定義の各種設定
}
// デストラクタ
~ModuleName() {
}
};
SC_MODULEマクロを使わないモジュールの構文
C++をわかっている人にとってはこちらの書き方の方がわかりやすいかもしれない。
#include <systemc.h>
class ModuleName
: public sc_module
{
public:
SC_HAS_PROCESS( ModuleName );
// コンストラクタ
ModuleName( sc_module_name m_name )
: sc_module( m_name )
{
}
};
SC_HAS_PROCESSはモジュール(のコンストラクタ)内でプロセス登録をしている場合は必ず必要になる。コンストラクタをSC_CTORマクロで記述している場合は、このSC_HAS_PROCESSの記述は必要ない。
もし、プロセス登録がないモジュールでもSC_HAS_PROCESSが宣言されていたからといってエラーになることはないので、とりあえず書いておくことをお薦めする。
SC_HAS_PROCESSは単なるtypedefのマクロにすぎない。
もし、プロセス登録がないモジュールでもSC_HAS_PROCESSが宣言されていたからといってエラーになることはないので、とりあえず書いておくことをお薦めする。
SC_HAS_PROCESSは単なるtypedefのマクロにすぎない。
モジュールの構成部品
モジュール:SC_MODULE
SystemCでハードウェアの1つの機能を記述するためのデザインの最小単位はSC_MODULEである。
Verilog-HDLでいうところのmoduleにあたる。
とにもかくにもこのSC_MODULEを作らなければ始まらない。
Verilog-HDLでいうところのmoduleにあたる。
とにもかくにもこのSC_MODULEを作らなければ始まらない。
SC_MODULEはマクロで、C++のクラスを宣言することになる。
SC_MODULEでは以下の要素を構築する。
- ポート(sc_port, sc_in, sc_out等)
- メンバ・チャネル(sc_signal, sc_buffer等)
- メンバ・データ(int, char, unsigned long等)
- コンストラクタ(SC_CTOR)
- デストラクタ
- プロセス・メソッド(プロセス)
- ヘルパ・メソッド
SC_MODULEクラスのコンストラクタ:SC_CTOR
SC_MODULEのコンストラクタはSC_CTORというマクロが用意されている。
SC_MODULEのコンストラクタではSystemC特有の以下の処理を行う。
- サブデザインの初期化/アロケーション
- サブデザインの接続(bind)
- SystemCカーネルへのプロセス登録(SC_METHOD, SC_THREAD, SC_CTHREAD)
- 静的センシティビティの設定(sensitive, reset_signal_is等)
- ユーザ定義の各種設定
実行の単位:プロセス(SC_METHOD, SC_THREAD, SC_CTHREAD)
ハードウェアを表現するためにSystemCでは並列処理を表現することができる。
並列処理は関数が単位となる。
SystemCでは、並列処理に設定した関数のことをプロセスと呼ぶ。
並列処理は関数が単位となる。
SystemCでは、並列処理に設定した関数のことをプロセスと呼ぶ。
プロセスの登録はSC_MODULEのコンストラクタで行う必要がある。それ以外では行わない。
SC_THREADのプロセス登録の例は次のとおり。
SC_THREADのプロセス登録の例は次のとおり。
SC_MODULE( Model ){
・・・
void func_thread();
// constructor
SC_CTOR( Model ) {
SC_THREAD( func_thread );
}
};
モジュール複製の回避
モジュール複製は望ましくない。
たいていは暗黙のルールでモジュールのコピーはしないもの。
コピーコンストラクタと代入演算子関数をprivateで定義することでモジュールのコピーを許さないようにできる。
次にその記述を示す。
たいていは暗黙のルールでモジュールのコピーはしないもの。
コピーコンストラクタと代入演算子関数をprivateで定義することでモジュールのコピーを許さないようにできる。
次にその記述を示す。
SC_MODULE( MyModel ) {
SC_CTOR( MyModel ) {
}
private:
MyModel( const MyModel& ) {} // コピーコンストラクタの禁止
MyModel &operator=( const MyModel& ) { return *this; } // 代入演算の禁止
};
こうすることで、万一モジュールの複製をしようとしても、コンパイル時にエラーとして怒られる。
マクロ定義
SC_MODULEのマクロ定義
SC_MODULEはsc_module.hで以下のように宣言されている。
#define SC_MODULE(user_module_name) \
struct user_module_name : ::sc_core::sc_module
SC_CTORのマクロ定義
SC_MODULEのコンストラクタであるSC_CTORはsc_module.hで次のように定義されている。
#define SC_CTOR(user_module_name) \
typedef user_module_name SC_CURRENT_USER_MODULE; \
user_module_name( ::sc_core::sc_module_name )
SC_HAS_PROCESSのマクロ定義
SC_HAS_PROCESSはsc_module.hで次のように定義されている。
#define SC_HAS_PROCESS(user_module_name) \
typedef user_module_name SC_CURRENT_USER_MODULE