TLM-2.0 ブロッキング・インターフェースLTモデル
ブロッキング・インターフェースを利用したLTモデルについて説明する。
ほとんどテンプレート的な説明になる。
TLM-2.0のモデリングはとっかかりがハードルが高いと思われるかもしれないが(わたし自身も含めて)、記述する方法さえわかれば、もしかすると純粋なSystemCよりも実装が簡単になるかもしれない(新たに実装モデルを考える必要がないので)。
ほとんどテンプレート的な説明になる。
TLM-2.0のモデリングはとっかかりがハードルが高いと思われるかもしれないが(わたし自身も含めて)、記述する方法さえわかれば、もしかすると純粋なSystemCよりも実装が簡単になるかもしれない(新たに実装モデルを考える必要がないので)。
注意:ここでは、説明を容易にするため通信部分と機能部分を分離していない。
概要
2つのモデル、イニシエータ・モデルとターゲット・モデルを用意する。
ブロッキング・インターフェースを利用。
抽象度はLT。
ブロッキング・インターフェースを利用。
抽象度はLT。
------------- FW ---------- | initiator | --------> | target | ------------- ---------- socket socket
TLMヘッダのインクルード
#include "tlm.h"
イニシエータ側の実装
イニシエータ側の実装は次の項目は必ず必要となる。
- tlm_bw_transport_if(ブロッキングI/F)を継承する
- tlm_initiator_socket(ソケット)をメンバとして定義する
- ソケットとモジュール(*this)をバインドする
- 2つの純粋仮想関数を実装する
- nb_transport_bw
- invalidate_direct_mem_ptr
SC_MODULE( Initiator ), tlm::tlm_bw_transport_if<>
{
tlm::tlm_initiator_socket<32> i_socket;
SC_HAS_PROCESS( Initiator );
Initiator( sc_module_name name )
: sc_module( name )
, i_socket( "i_socket" )
{
i_socket.bind( *this ); // I/Fとバインド
SC_THREAD( thread0 );
}
void thread0()
{
// ここにイニシエータの処理を記述する
// たとえば、ここでi_socket.b_transport()を呼ぶ
}
tlm::tlm_sync_enum nb_transport_bw( tlm::tlm_generic_payload& trans, tlm::tlm_phase &phase, sc_time& time )
{
// ここにターゲット側から呼ばれるバック・ワード処理を記述する
// とりあえず実装しない場合は
// trans.set_response_status( tlm::TLMGENERIC_ERROR_RESPONSE );
// return tlm::TLM_COMPLETED;
}
void invalidate_direct_mem_ptr( sc_dt::uint64 a, sc_dt::uint64 b)
{
// DMI unused
}
ターゲット側の実装
ターゲット側の実装は次の項目は必ず必要となる
- tlm_fw_transport_if(ブロッキングI/F)を継承する
- tlm_target_socket(ソケット)をメンバとして定義する
- ソケットとモジュール(*this)をバインドする
- 4つの純粋仮想関数を実装する
- b_transport
- nb_transport_fw
- transport_dbg
- get_direct_mem_ptr
SC_MODULE( Target ), tlm::tlm_fw_transport_if<>
{
tlm::tlm_target_socket<32> t_socket;
SC_HAS_PROCESS( Target );
Target( sc_module_name name )
: sc_module( name )
, t_socket( "t_soket" )
{
t_socket.bind( *this ); // I/Fとバインド
}
void b_transport( tlm::tlm_generic_payload &trans, sc_time &time )
{
// ここにターゲット側の機能を記述する
}
tlm::tlm_sync_enum nb_transport_fw( tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, sc_time &time )
{
// ここにターゲット側の機能を記述する
}
unsigned int transport_dbg( tlm::tlm_generic_payload &trans)
{
return 0; // Debug not supported
}
bool get_direct_mem_ptr( tlm::tlm_generic_payload &trans, tlm::tlm_dmi& dmi)
{
return false; // DMI not supported
}
トップ(イニシエータとターゲットの接続)
SC_MODULE( TOP )
{
SC_CTOR( TOP )
{
target= new Target( "target" );
initiator = new Initiator( "initiator" );
initiator->i_socket( target->t_socket );
}
~TOP()
{
delete target;
delete initiator;
}
Initiator *initiator;
Target *target;
};
説明
イニシエータとターゲットはインターフェースを継承する。
そのため、モジュール自体が階層チャネルのような性質を持つことになるため、モジュール自体にbindすることができる。
そのため、モジュール自体が階層チャネルのような性質を持つことになるため、モジュール自体にbindすることができる。
実装する際に重要になってくるのは、tlm_generic_payloadとは何かを理解することと実装した関数b_transport,nb_transport_fwの使用方法を理解することである。
サンプル
b_lt_model.tgz- main.cpp
- TOP.h
- TOP.cpp
- Initiator.h
- Initiator.cpp
- Target.h
- Target.cpp
- Makefile
内容
sc_main |===> top(TOP) |===> initiator(Initiator) |===> target(Target)
- sc_mainでTOPをインスタンス
- TOPではInitiatorとTargetをインスタンス
- TOPでInitiatorとTargetのソケットを接続
- Initiatorはソケットを経由してb_transportに対してWrite/Readトランザクションをだす
- Targetはレジスタを実装する
- Targetはb_tarnsportによりトランザクションを受け取ったら、レジスタWrite/Read動作を実行
参考文献
添付ファイル