bambooflow Note

ブロッキング・インターフェースLTモデル

最終更新:

bambooflow

- view
メンバー限定 登録/ログイン

TLM-2.0 ブロッキング・インターフェースLTモデル

ブロッキング・インターフェースを利用したLTモデルについて説明する。
ほとんどテンプレート的な説明になる。
TLM-2.0のモデリングはとっかかりがハードルが高いと思われるかもしれないが(わたし自身も含めて)、記述する方法さえわかれば、もしかすると純粋なSystemCよりも実装が簡単になるかもしれない(新たに実装モデルを考える必要がないので)。

注意:ここでは、説明を容易にするため通信部分と機能部分を分離していない。



概要

2つのモデル、イニシエータ・モデルとターゲット・モデルを用意する。
ブロッキング・インターフェースを利用。
抽象度は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することができる。

実装する際に重要になってくるのは、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動作を実行


参考文献

添付ファイル
記事メニュー
目安箱バナー