bambooflow Note

Interconnect

最終更新:

bambooflow

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

Interconnect Component

イニシエータとターゲットの間のモデル。
ここでは、ブロッキングI/Fを利用したLTモデルを説明。
b_transoprtメソッドのみの実装を記述。そのほかのメソッドは今回は非サポート。


サンプル

b_lt_model_plus_router.tgz

構成

  • インスタンス関係
sc_main
  |==> top(TOP)
       |==> initiator(Initiator)
       |==> router(Router)
       |==> target[4](Target)

  • 接続関係
initiator ==> router +==> target[0]
                     |==> target[1]
                     |==> target[2]
                     |==> target[3]

TOP

トップでインスタンスするモジュールは、
  • イニシエータ1つ(i_socket)
  • ルータ1つ(t_socket, i_socket[4])
  • ターゲット4つ(t_socket)

  • TOP.h
#ifndef __TOP_H_
#define __TOP_H_

#include <systemc.h>

class Initiator;
class Target; 
class Router; 
 
SC_MODULE( TOP )
{
public:
    TOP( sc_module_name name ); 
    ~TOP(); 
 
//private:
    enum { TARGET_MAX = 256 };
 
    Initiator     *initiator;
    Target        *target[TARGET_MAX];
    Router        *router;
 
private:
    const unsigned int targetNum; 
};
 
#endif /* __TOP_H_ */
 

  • TOP.cpp
#include "TOP.h"
#include "tlm.h"

#include "Initiator.h"
#include "Target.h"
#include "Router.h"

// constructor
TOP::TOP( sc_module_name name )
    : sc_module( name )
    , targetNum( 4 ) // <== setting
{
    sc_assert( 0<targetNum && targetNum<TARGET_MAX );
 
    // instances
    initiator = new Initiator( "initiator" );
    router = new Router( "router", targetNum );
 
    for (unsigned int i=0; i<targetNum; i++) {
        char t_name[20];
        sprintf( t_name, "target_%d",  i );
        target[i] = new Target( t_name );
    }
 
    // binding
    initiator->i_socket.bind( router->t_socket );
    for (unsigned int i=0; i<targetNum; i++)
        router->i_socket[i]->bind( target[i]->t_socket );
}
 
// destructor
TOP::~TOP()
{
    delete initiator;
    delete router; 
    for (unsigned int i=0; i<targetNum; i++) {
        delete target[i];
    }
}
 


Router

ルータはイニシエータからのリクエストを接続されているターゲットに渡す中間モジュール。
複数ターゲットが接続されているので、上位ビットをみてそれぞれのターゲットにリクエストを振り分ける。

  • Router.h
#ifndef __ROUTER_H_
#define __ROUTER_H_

#include <systemc.h>
#include "tlm.h"

SC_MODULE( Router )
    , public tlm::tlm_fw_transport_if<>
    , public tlm::tlm_bw_transport_if<>
{
    enum { TARGET_MAX = 256 };
 
    tlm::tlm_initiator_socket<32>  *i_socket[TARGET_MAX];
    tlm::tlm_target_socket<32>     t_socket;
 
    SC_HAS_PROCESS( Router );
    Router( sc_module_name name, const unsigned int target_um=4 );
    ~Router();
 
protected:
    // I/F functions
    // FW   
    virtual void b_transport( tlm::tlm_generic_payload &trans, sc_time &time ) ;
    virtual tlm::tlm_sync_enum nb_transport_fw( tlm::tlm_generic_payload
            &trans, tlm::tlm_phase &phase, sc_time &time );
    virtual unsigned int transport_dbg( tlm::tlm_generic_payload &trans );
    virtual bool get_direct_mem_ptr( tlm::tlm_generic_payload &trans, tlm::tlm_dmi& dmi);
    // BW   
    virtual tlm::tlm_sync_enum nb_transport_bw(
            tlm::tlm_generic_payload& trans, tlm::tlm_phase &phase, sc_time& time ); 
    virtual void invalidate_direct_mem_ptr( sc_dt::uint64 a, sc_dt::uint64 b);
 
    // functions
    unsigned int decode_address( unsigned int address, unsigned int& masked_address );
    sc_dt::uint64 compose_address( unsigned int target_nr, sc_dt::uint64 address);
 
private:
    const unsigned int targetNum;
 
};
 
#endif /* __ROUTER_H_ */
 

  • Router.cpp
#include "Router.h"

// constructor
Router::Router( sc_module_name name, const unsigned int target_num )
    : sc_module( name )
    //, i_socket( "i_socket" )
    , t_socket( "t_socket" )
    , targetNum( target_num )
{
    sc_assert( (0 < targetNum) && (targetNum < TARGET_MAX) );
 
    for (unsigned int i=0; i<targetNum; i++) {
        char socket_name[20];
        sprintf( socket_name, "i_socket_%d",  i );
        i_socket[i] = new tlm::tlm_initiator_socket<32>( socket_name );
        i_socket[i]->bind( *this );  // I/Fとバインド
    }
 
    t_socket.bind( *this );  // I/Fとバインド
}
 
Router::~Router()
{
    for (unsigned int i=0; i<targetNum; i++) {
        delete i_socket[i];
    }
}
 
unsigned int Router::decode_address( unsigned int address, unsigned int& masked_address )
{
    unsigned int target_nr =  (address >> 16) & 0xff; // target_nr is 0~255
    masked_address = address & 0xffff; 
    return target_nr;
}
 
sc_dt::uint64 Router::compose_address( unsigned int target_nr, sc_dt::uint64 address)
{
    return (target_nr << 16) | (address & 0xffff);
}
 
 
// FW
void Router::b_transport( tlm::tlm_generic_payload &trans, sc_time &time )
{
    trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE  );
    unsigned int address = static_cast<unsigned int>(trans.get_address());
    unsigned int masked_address; // mask: 0x0000ffff
    unsigned int target_nr;
 
    target_nr = decode_address( address, masked_address );
 
    if (target_nr < targetNum) {
        trans.set_address( masked_address );
        (*i_socket[target_nr])->b_transport( trans, time );
    }
    else {
        cout << name() << " : ERROR, can not access Target No." << target_nr << endl;
        trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE  );
    }
}
 
// FW
tlm::tlm_sync_enum Router::nb_transport_fw(
        tlm::tlm_generic_payload &trans,
        tlm::tlm_phase &phase,
        sc_time &time )
{
    cout << "nb_transport_fw is not supoorted." << endl;
    trans.set_response_status( tlm::TLM_GENERIC_ERROR_RESPONSE );
 
    return tlm::TLM_COMPLETED;
}
 
// FW
unsigned int Router::transport_dbg( tlm::tlm_generic_payload &trans )
{
    //sc_dt::uint64 masked_address; 
    //unsigned int target_nr = decode_address( trans.get_address(), masked_address );
    //return (*i_socket[target_nr])->transport_dbg( trans );
    return 0;  // Debug not supported
}
 
bool Router::get_direct_mem_ptr( tlm::tlm_generic_payload &trans, tlm::tlm_dmi& dmi)
{
    //uint64 masked_address;
    //unsigned int target_nr = decode_address( trans.get_address(), masked_address );
    //bool status = (*i_socket[target_nr])->get_direct_mem_ptr( masked_address, dmi );
    //dmi.set_start_address( compose_address( target_nr, dmi.get_start_address() ) );
    //dmi.set_end_address( compose_address( target_nr, dmi.get_end_address() ) );
    //return status;
    return false; // DMI not supported
}
 
// BW 
tlm::tlm_sync_enum Router::nb_transport_bw( tlm::tlm_generic_payload& trans, tlm::tlm_phase &phase, sc_time& time )
{
    // not support
    trans.set_response_status( tlm::TLM_GENERIC_ERROR_RESPONSE );
    return tlm::TLM_COMPLETED;
}
 
// BW 
void Router::invalidate_direct_mem_ptr( sc_dt::uint64 a, sc_dt::uint64 b)
{
    // DMI unused
    // t_socket->invalidate_direct_mem_ptr( 0, (sc_dt::uint64)-1 );
}
 

タグ:

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