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