Show basicPorts.h syntax highlighted
// LICENSETEXT
//
// Copyright (C) 2005,2006 :
// GreenSocs Ltd
// (http://www.greensocs.com/),
//
// email: info@greensocs.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
// ENDLICENSETEXT
#ifndef __BASICPORTS_H__
#define __BASICPORTS_H__
#include "gstlm/tlm_b_if.h"
#include "gstlm/tlm_port.h"
#include "utils/memoryutils.h"
namespace tlm {
template <class TRANSACTION_P>
class tlm_master_b_transact_error_t: public virtual tlm_b_if<TRANSACTION_P>
{
void b_transact( TRANSACTION_P ) {
SC_REPORT_ERROR( sc_core::SC_ID_INTERNAL_ERROR_, "Tryed to access blocking interface from a master as a target" );
}
};
template<class _T1, class _T2>
struct unevenpair: public std::pair<_T1, _T2>
{
inline bool
same(const unevenpair<_T1, _T2>& __x)
{ return __x.first == this->first ;}
// this operator only compares the first element of the pair (for performance reasons)
inline bool operator == (const unevenpair<_T1, _T2>& __x) {
return __x.first == this->first;
}
// this operator only compares the first element of the pair (for performance reasons)
inline bool operator != (const unevenpair<_T1, _T2>& __x) {
return __x.first != this->first;
}
unevenpair(const _T1 &a, const _T2 &b) : std::pair<_T1, _T2>(a,b) { };
unevenpair() : std::pair<_T1,_T2>() { };
unevenpair(const unevenpair<_T1, _T2>& __p) : std::pair<_T1,_T2>(__p) { };
};
//---------------------------------------------------------------------------
/**
* Base for initiator ports, who owns the phases.
*/
//---------------------------------------------------------------------------
template <class TRANSACTION, class ACCESS, class PHASE,
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class ACCESS_P = boost::shared_ptr<ACCESS>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P,PHASE_P> >
class initiator_port :
public tlm_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>
{
public:
typedef TRANSACTION transaction;
typedef TRANSACTION_P transactionHandle;
typedef ACCESS_P accessHandle;
typedef PHASE_P phaseHandle;
typedef TRANSACTION_PHASE pair_type;
initiator_port( sc_module_name port_name ) :
tlm_port<tlm_b_if<TRANSACTION_P>,pair_type>(port_name)
{
#ifdef DUST_ENABLE
DUST_MASTER_PORT("BasicInitiatorPort", "GSTLM");
#endif
tlm_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::b_in(tlm_master_b_transact_error);
}
private:
//removed static qualifier because if every init_port is bound to the same (static) transact_error class
//bindings to a target_multi_port (router) will fail, since the kernel
//does not allow binding the same interface multiple times to the same port
tlm_master_b_transact_error_t<TRANSACTION_P> tlm_master_b_transact_error;
};
/*
template <class TRANSACTION, class ACCESS, class PHASE,
class TRANSACTION_P,
class ACCESS_P,
class PHASE_P,
class TRANSACTION_PHASE>
tlm_master_b_transact_error_t<TRANSACTION_P> initiator_port<TRANSACTION,ACCESS,PHASE,TRANSACTION_P,ACCESS_P,PHASE_P,TRANSACTION_PHASE>::tlm_master_b_transact_error;
*/
//---------------------------------------------------------------------------
/**
* Base for initiator ports, who owns the phases and is able to handle mutiple targets
*/
//---------------------------------------------------------------------------
template <class TRANSACTION, class ACCESS, class PHASE,
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class ACCESS_P = boost::shared_ptr<ACCESS>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P,PHASE_P> >
class initiator_multi_port :
public tlm_multi_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>
{
public:
typedef TRANSACTION transaction;
typedef TRANSACTION_P transactionHandle;
typedef ACCESS_P accessHandle;
typedef PHASE_P phaseHandle;
typedef TRANSACTION_PHASE pair_type;
initiator_multi_port( sc_module_name port_name ) :
tlm_multi_port<tlm_b_if<TRANSACTION_P>, pair_type >(port_name)
{
#ifdef DUST_ENABLE
DUST_MASTER_PORT("BasicInitiatorMultiPort", "GSTLM");
#endif
tlm_multi_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::b_in(tlm_master_b_transact_error);
}
private:
//removed static qualifier because if every init_port is bound to the same (static) transact_error class
//bindings to a target_multi_port (router) will fail, since the kernel
//does not allow binding the same interface multiple times to the same port
tlm_master_b_transact_error_t<TRANSACTION_P> tlm_master_b_transact_error;
};
//---------------------------------------------------------------------------
/**
* Base for target ports.
*/
//---------------------------------------------------------------------------
template <class TRANSACTION, class ACCESS, class PHASE,
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class ACCESS_P = boost::shared_ptr<ACCESS>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P,PHASE_P> >
class target_port :
public tlm_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>
{
public:
typedef TRANSACTION transaction;
typedef TRANSACTION_P transactionHandle;
typedef ACCESS_P accessHandle;
typedef PHASE_P phaseHandle;
typedef TRANSACTION_PHASE pair_type;
target_port( sc_module_name port_name ) :
tlm_port<tlm_b_if<TRANSACTION_P>,pair_type>(port_name)
{
#ifdef DUST_ENABLE
DUST_SLAVE_PORT("BasicTargetPort", "GSTLM");
#endif
}
accessHandle get_transactionHandle() {return this->get_payload().first;};
phaseHandle get_phase() {return this->get_payload().second;};
//transactionHandle get_transaction() {return this->get_payload().first;};
};
//---------------------------------------------------------------------------
/**
* Base for target ports, which is able to accessed by multiple initiators.
*/
//---------------------------------------------------------------------------
template <class TRANSACTION, class ACCESS, class PHASE,
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class ACCESS_P = boost::shared_ptr<ACCESS>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P,PHASE_P> >
class target_multi_port :
public tlm_multi_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>
{
public:
typedef TRANSACTION transaction;
typedef TRANSACTION_P transactionHandle;
typedef ACCESS_P accessHandle;
typedef PHASE_P phaseHandle;
typedef TRANSACTION_PHASE pair_type;
target_multi_port( sc_module_name port_name ) :
tlm_multi_port<tlm_b_if<TRANSACTION_P>,pair_type>(port_name)
{
#ifdef DUST_ENABLE
DUST_SLAVE_PORT("BasicTargetMultiPort", "GSTLM");
#endif
}
accessHandle get_transactionHandle() {return this->get_payload().first;};
phaseHandle get_phase() {return this->get_payload().second;};
transactionHandle get_transaction() {return this->get_payload().first;};
};
//---------------------------------------------------------------------------
/**
* Specialized initiator port for the master port, who owns the transactions.
*/
//---------------------------------------------------------------------------
template <class TRANSACTION, class ACCESS, class PHASE,
class CREATED_TRANSACTION = TRANSACTION,
class CREATED_TRANSACTION_P = boost::shared_ptr<CREATED_TRANSACTION>,
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class ACCESS_P = boost::shared_ptr<ACCESS>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P,PHASE_P> >
class master_port :
public initiator_port<TRANSACTION,ACCESS,PHASE,TRANSACTION_P,ACCESS_P,PHASE_P,TRANSACTION_PHASE>
{
public:
typedef TRANSACTION transaction;
typedef TRANSACTION_P transactionHandle;
typedef ACCESS_P accessHandle;
typedef PHASE_P phaseHandle;
typedef TRANSACTION_PHASE pair_type;
typedef CREATED_TRANSACTION_P created_transaction_handle;
typedef CREATED_TRANSACTION created_transaction;
master_port( sc_module_name port_name ) :
initiator_port<TRANSACTION,ACCESS,PHASE,TRANSACTION_P,ACCESS_P,PHASE_P,TRANSACTION_PHASE>(port_name)
{
// use in-port pointer address as unique master ID (this is important to make genericRouter work)
MasterPortNumber = (unsigned long) &this->in;
#ifdef DUST_ENABLE
this->out.setMasterID(MasterPortNumber);
#endif
}
~master_port(){
}
/**
* Create a transaction with a unique master ID.
*/
created_transaction_handle create_transaction() {
created_transaction_handle tmp=TransactionFactory.create();
tmp->set_mID(MasterPortNumber);
return tmp;
}
unsigned int get_master_port_number() {
return MasterPortNumber;
}
accessHandle get_transactionHandle() {return boost::static_pointer_cast<created_transaction>(this->get_payload().first);};
phaseHandle get_phase() {return this->get_payload().second;};
created_transaction_handle get_transaction() {return this->get_payload().first;};
private:
ObjectFactory<created_transaction_handle> TransactionFactory;
unsigned int MasterPortNumber;
};
template <class FORWARDS, class CONNECTS_TO, class TRANSACTION, class PHASE,
class TRANSACTION_P = boost::shared_ptr<TRANSACTION>,
class PHASE_P = PHASE,
class TRANSACTION_PHASE = unevenpair<TRANSACTION_P,PHASE_P>
>
class basic_port_forwarder : public tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>{
public:
basic_port_forwarder(sc_module_name name)
: tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>(name)
{
#ifdef DUST_ENABLE
DUST_MASTER_PORT("BasicPortForwarder", "GSTLM");
#endif
}
//here we override the forward method to decide whether the port should be forwarded or bound
virtual void forward(tlm_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>& port_)
{
FORWARDS* pfw= dynamic_cast<FORWARDS*>(&port_);
CONNECTS_TO* pct= dynamic_cast<CONNECTS_TO*>(&port_);
if (pfw) {
cout<<sc_module::name()<<" : forwarding the port named "<<port_.name()<<endl<<flush;
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::forward(port_);
}
if (pct) {
cout<<sc_module::name()<<" : binding the port named "<<port_.name()<<endl<<flush;
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::bind(port_);
}
}
//here we override the forward method to decide whether the port should be forwarded or bound
virtual void forward(tlm_multi_port<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>& port_)
{
FORWARDS* pfw= dynamic_cast<FORWARDS*>(&port_);
CONNECTS_TO* pct= dynamic_cast<CONNECTS_TO*>(&port_);
if (pfw) {
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::forward(port_);
}
if (pct) {
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::bind(port_);
}
}
//connect to target
void operator () ( CONNECTS_TO& port_ )
{
cout<<sc_module::name()<<" : binding to the port named "<<port_.name()<<endl<<flush;
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::bind(port_);
}
//connect to target forward
void operator () ( basic_port_forwarder<CONNECTS_TO, FORWARDS, TRANSACTION, PHASE>& port_ )
{
cout<<sc_module::name()<<" : binding to the fw port named "<<port_.name()<<endl<<flush;
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::bind(port_);
}
//forward another forward
void operator () ( basic_port_forwarder<FORWARDS, CONNECTS_TO, TRANSACTION, PHASE>& port_ )
{
cout<<sc_module::name()<<" : forwarding to the fw port named "<<port_.name()<<endl<<flush;
tlm_port_forwarder_base<tlm_b_if<TRANSACTION_P>,TRANSACTION_PHASE>::forward(port_);
}
};
} // end of namespace tlm
#endif
See more files for this project here