generic.static_casts.h from GreenSocs at Krugle
Show generic.static_casts.h syntax highlighted
///////////////////////////////////////////////////////////////////////////////
/// \file generic.static_casts.h
/// An implementation of the generic protocol that uses static_casts.
/// Gives 12% speed up over dynamic_cast version.
///////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
/**
* A generic phase class.
* This is a set of phases and access functions
* to form the GreenBus generic protocol.
*/
//---------------------------------------------------------------------------
class GenericPhase // "Phases for the Generic Protocol";
{
public:
/// the phases of the generic protocol
enum {
Idle = 0,
RequestValid,RequestAccepted,RequestError,
DataValid, DataAccepted, DataError,
ResponseValid,ResponseAccepted, ResponseError,
LAST_GENERIC_PHASE
};
gs_uint32 state;
GenericSimulationModeType sim_mode;
gs_uint32 BurstNumber;
/**
* Create phase with default state (Idle).
*/
GenericPhase()
: state(Idle), sim_mode(MODE_BA), BurstNumber(0)
{}
GenericPhase(sc_event &_initiator_update_event, sc_event &_target_update_event)
: state(Idle), sim_mode(MODE_CT), BurstNumber(0)
{}
/**
* Create phase.
* @param s Phase state
*/
GenericPhase(gs_uint32 s)
: state(s), sim_mode(MODE_BA), BurstNumber(0)
{}
/**
* Create phase.
* @param s Phase state
* @param b Burst number
*/
GenericPhase(gs_uint32 s, gs_uint32 b)
: state(s), sim_mode(MODE_BA), BurstNumber(b)
{}
/// copy constructor
GenericPhase(const GenericPhase &p) {
*this = p; // use copy-operator
}
/// copy operator
GenericPhase & operator=(const GenericPhase &p) {
if (&p==this)
return *this;
state=p.state;
sim_mode=p.sim_mode;
BurstNumber=p.BurstNumber;
return *this;
}
/// set the simulation mode for this phase
inline void setSimulationMode(GenericSimulationModeType m) {
sim_mode = m;
}
/// get the simulation mode for this phase
inline GenericSimulationModeType getSimulationMode() {
return sim_mode;
}
/// has a request atom been sent by the master?
inline bool isRequestValid() { return state == RequestValid; }
/// has a request atom been accepted by the slave?
inline bool isRequestAccepted() { return state == RequestAccepted; }
/// has the slave replied an error on a master's request atom?
inline bool isRequestError() { return state == RequestError; }
/// has a data atom been sent by the master?
inline bool isDataValid() { return state == DataValid; }
/// has a data atom been accepted by the slave?
inline bool isDataAccepted() { return state == DataAccepted; }
/// has the slave replied an error on a master's data atom?
inline bool isDataError() { return state == DataError; }
/// has a response atom been sent by the slave?
inline bool isResponseValid() { return state == ResponseValid; }
/// has a response atom been accepted by the master?
inline bool isResponseAccepted() { return state == ResponseAccepted; }
/// has the master replied an error on a slave's response atom?
inline bool isResponseError() { return state == ResponseError; }
/// get a string description of the current protocol phase
std::string toString() {
if (isRequestValid()) return std::string("RequestValid");
else if (isRequestAccepted()) return std::string("RequestAccepted");
else if (isRequestError()) return std::string("RequestError");
else if (isDataValid()) return std::string("DataValid");
else if (isDataAccepted()) return std::string("DataAccepted");
else if (isDataError()) return std::string("DataError");
else if (isResponseValid()) return std::string("ResponseValid");
else if (isResponseAccepted()) return std::string("ResponseAccepted");
else if (isResponseError()) return std::string("ResponseError");
else {
std::stringstream ss;
ss << "unknown phase (state=" << state
<< ", simulation mode=" << sim_mode << ")";
return ss.str();
}
}
};
#define REQUESTPHASE GenericPhase::RequestValid, GenericPhase::RequestAccepted, GenericPhase::RequestError
#define DATAPHASE GenericPhase::DataValid, GenericPhase::DataAccepted, GenericPhase::DataError
#define RESPONSEPHASE GenericPhase::ResponseValid, GenericPhase::ResponseAccepted, GenericPhase::ResponseError
#define INITATTRIBUTE(name) \
name.setName(#name)
#define ADDTOPHASE(name, ...) \
setPhases(name, false, __VA_ARGS__ , 65563 )
#define ADDEXTTOPHASE(name, ...) \
setPhases(name, true, __VA_ARGS__ , 65563 )
class GenericMasterAccess;
class GenericTargetAccess;
class GenericRouterAccess;
//---------------------------------------------------------------------------
/**
* A generic transaction class.
* This is the GreenBus transaction container.
* See GreenBus user manual for usage examples.
* See GenericMasterAcess, GenericTargetAccess, and GenericRouterAccess for
* documentation of the attribute access methods.
*/
//---------------------------------------------------------------------------
class GenericTransaction
: protected TransactionBase
{
#ifdef DUST_ENABLE
friend class scv_extensions<GenericTransaction>;
#endif
protected:
// quarks ///////////////////////////////////////////////////////////////////
MAddr mAddr;
MBurstLength mBurstLength, sBurstLength;
MCmd mCmd;
MData msData;
MDataWidth mDataWidth;
SDataWidth sDataWidth;
SResp sResp;
Error mError;
Error sError;
MID mID;
// attribute iterators //////////////////////////////////////////////////////
bool is_extended;
std::string *extendedType;
attribute_map *attribs;
attribute_map *extended_attribs;
// CT simulation mode ///////////////////////////////////////////////////////
sc_event initiator_update_event, target_update_event;
public:
// quark access /////////////////////////////////////////////////////////////
/// set target address
inline void setMAddr(const MAddr& _mAddr){mAddr=_mAddr;}
/// set master burst length ('0' implies variable length burst, then you have to check SBurstLength in slave reply)
inline void setMBurstLength(const MBurstLength& _mBurstLength){ mBurstLength=_mBurstLength; }
inline void setSBurstLength(const SBurstLength& _sBurstLength){ sBurstLength=_sBurstLength; }
/// set master command (see GenericMCmdType)
inline void setMCmd(const MCmd& _mCmd){mCmd=_mCmd;}
/// set master id
inline void setMID(const MID& _mID) {mID=_mID;}
/// set master data (i.e. set the data pointer in the transaction container to the given GSDataType)
inline void setMData(const GSDataType& _mData){msData.set(_mData);}
inline void setMDataWidth(const MDataWidth& _mDataWidth){mDataWidth=_mDataWidth;}
inline void setSDataWidth(const SDataWidth& _sDataWidth){sDataWidth=_sDataWidth;}
inline void setSResp(const SResp& _sResp){ sResp = _sResp; }
inline void setSData(MData& _sData) {
if (_sData.isPointer())
msData.setPointer(_sData.getPointer());
else
msData.deepcopyFrom(const_cast<MData&>(_sData));
}
/// get target address
inline const MAddr& getMAddr() const {return mAddr; }
/// get master cmd
inline const MCmd& getMCmd() const {return mCmd; }
/// get master id
inline const MID& getMID() const {return mID;}
/// get access to the transaction data (see GSDataType)
inline const MData& getMData() const {return msData; }
inline void getMData(const MData & _dst ) { msData.deepcopyTo(const_cast<MData&>(_dst)); }
/// get master data bus width (# bytes that are transferred by the master in one cycle). This value is set by the initiator port.
inline const MDataWidth& getMDataWidth() const {return mDataWidth;}
/// get slave data bus width (# bytes that can be received by the slave in one cycle). This value is set by the target port.
inline const SDataWidth& getSDataWidth() const {return sDataWidth;}
/// get the master burst length
inline const MBurstLength& getMBurstLength() const {return mBurstLength; }
/// get slave burst length
inline const SBurstLength& getSBurstLength() const {return sBurstLength; }
/// get the slave response (see GenericSRespType)
inline const SResp& getSResp() const {return sResp; }
/// get access to the transaction data (see GSDataType)
inline MData& getSData() {return msData; }
/// set the master error (see GenericError)
inline void setMError(const Error& _mError) {mError=_mError;}
/// get the master error (see GenericError)
inline const Error getMError() const {return mError;}
/// set the slave error (see GenericError)
inline void setSError(const Error& _sError) {sError=_sError;}
/// get the slave error (see GenericError)
inline const Error getSError() const {return sError;}
// attribute iterators //////////////////////////////////////////////////////
/// get an iterator over all standard attributes of this transaction container
inline attribute_iterator getAttributeIterator(int phase){
if (attribs==NULL)
createAttributeIterator();
return attribs->find(phase);
}
/// get an iterator pointing to the last attribute of this transaction container
inline attribute_iterator lastAttribute(int phase) {
if (attribs==NULL)
createAttributeIterator();
if (attribs->find(phase)==attribs->end())
return attribs->end() ;
else
return attribs->upper_bound(phase);
}
/// get an iterator over the extended attributes of this transaction container
inline attribute_iterator getExtendedAttributeIterator(int phase){
if (extended_attribs==NULL)
createExtendedAttributeIterator();
return extended_attribs->find(phase);
}
/// get an iterator pointing to the last extended attribute of this transaction container
inline attribute_iterator lastExtendedAttribute(int phase) {
if (extended_attribs==NULL)
createExtendedAttributeIterator();
if (extended_attribs->find(phase)==extended_attribs->end())
return extended_attribs->end() ;
else
return extended_attribs->upper_bound(phase);
}
/// map an attribute to a set of phases (this function is used by the attribute iterators)
inline void setPhases(AttributeRoot& attr, bool extended,...) {
va_list ap;
va_start(ap, extended);
for (;;){
int a=va_arg(ap, int);
if (a==65563) break;
if (extended)
extended_attribs->insert(std::make_pair(a, &attr));
else
attribs->insert(std::make_pair(a, &attr));
}
va_end(ap);
}
/// does this transaction container contain extended attributes?
inline bool isExtended(){
return is_extended;
}
/// get the extension type of this transaction container
/**
* This method is to be implemented in extended transaction containers.
* It should create a string with the name of the extended transaction.
*/
inline virtual std::string &getExtendedType() {
if (extendedType==NULL) {
extendedType = new std::string("N/A");
}
return *extendedType;
}
/// create the attribute iterator.
/**
* This method has to be called before using the attribute iterator
* the first time. It creates a vector with all attributes of this
* transaction container.
*/
void createAttributeIterator() {
sc_assert(attribs==NULL);
attribs=new attribute_map();
INITATTRIBUTE(mCmd);
ADDTOPHASE(mCmd,REQUESTPHASE);
INITATTRIBUTE(mAddr);
ADDTOPHASE(mAddr,REQUESTPHASE, DATAPHASE, RESPONSEPHASE);
INITATTRIBUTE(msData);
ADDTOPHASE(msData,DATAPHASE, RESPONSEPHASE);
INITATTRIBUTE(mDataWidth);
ADDTOPHASE(mDataWidth, REQUESTPHASE);
INITATTRIBUTE(sDataWidth);
ADDTOPHASE(sDataWidth, REQUESTPHASE);
INITATTRIBUTE(mBurstLength);
ADDTOPHASE(mBurstLength,REQUESTPHASE);
INITATTRIBUTE(sResp);
ADDTOPHASE(sResp, RESPONSEPHASE);
INITATTRIBUTE(mError);
ADDTOPHASE(mError, REQUESTPHASE, DATAPHASE, RESPONSEPHASE);
INITATTRIBUTE(sError);
ADDTOPHASE(sError, REQUESTPHASE, DATAPHASE, RESPONSEPHASE);
INITATTRIBUTE(mID);
ADDTOPHASE(mID, REQUESTPHASE, DATAPHASE, RESPONSEPHASE);
}
/// create the extended attribute iterator.
/**
* This method has to be called before using the extended attribute
* iterator the first time. It creates a map with all extendeded
* attributes of this transaction container.
* Note: Extended attributes are declared by transaction containers
* that INHERIT from this class. They must implement this
* virtual method as well, and the implementation must call
* the createExtendedAtteributeIterator() method of the base
* class (e.g. a PLBTransaction would call
* GenericTransaction::createExtendedAttributeIterator()
* at the beginning of its createExtendedAttributeIterator method,
* and a PLBExtendedTransaction which inherits from PLBTransaction
* would call PLBTransaction::createExtendedAttributeIterator()
* at the beginning of its createExtendedAttributeIterator method.
* This is to make sure that ALL extended attributes of all
* extended transaction containers in the inheritence tree are added
* to the extended_attributes map.
*/
virtual void createExtendedAttributeIterator() {
sc_assert(extended_attribs==NULL);
extended_attribs=new attribute_map();
// override this method in extended transactions and init your extended
// attributes here.
}
// construction /////////////////////////////////////////////////////////////
/**
* Create a generic transaction. You should not use this constructor
* directly. Always use master_port::createTransaction().
*/
GenericTransaction()
: mBurstLength(0), // only init important flags
sBurstLength(0),
mError(0),
sError(0),
is_extended(false),
extendedType(NULL),
attribs(NULL),
extended_attribs(NULL)
{}
/// copy constructor
GenericTransaction(const GenericTransaction &t) {
*this = t; // use copy-operator
}
void reset(){
mBurstLength=0;
sBurstLength=0;
mError=0;
sError=0;
}
/// destructor
~GenericTransaction() {
if (attribs!=NULL) delete attribs;
if (extended_attribs!=NULL) delete extended_attribs;
if (extendedType!=NULL) delete extendedType;
}
/// copy operator
GenericTransaction & operator=(const GenericTransaction &t) {
if (&t==this)
return *this;
mAddr = t.mAddr;
mBurstLength = t.mBurstLength;
sBurstLength = t.sBurstLength;
mCmd = t.mCmd;
msData.deepcopyFrom(t.msData);
mDataWidth = t.mDataWidth;
sDataWidth = t.sDataWidth;
sResp = t.sResp;
mError = t.mError;
sError = t.sError;
mID = t.mID;
is_extended = t.is_extended;
// TODO: check if quarks are missing
return *this;
}
// get an access handle to this transaction /////////////////////////////////
/// Get the router access set to this transaction
GenericRouterAccess &getRouterAccess() {
return reinterpret_cast<GenericRouterAccess&>(*this);
}
/// Get the master access set to this transaction
GenericMasterAccess &getMasterAccess() {
return reinterpret_cast<GenericMasterAccess&>(*this);
}
/// Get the target access set to this transaction
GenericTargetAccess &getTargetAccess() {
return reinterpret_cast<GenericTargetAccess&>(*this);
}
// CT simulation helpers ////////////////////////////////////////////////////
/// notify a CT slave of a quark update
inline void notifyTargetUpdate() {target_update_event.notify();}
/// notify a CT slave of a quark update
inline void notifyTargetUpdate(const sc_time &t) {target_update_event.notify(t);}
/// notify a CT slave of a quark update
inline void notifyTargetUpdate(const double d, const sc_time_unit u) {target_update_event.notify(d,u);}
/// get the initiator update event ( use in slave to trigger on master CT quark update notification)
inline const sc_event& getInitiatorUpdateEvent() const {return initiator_update_event;}
/// wait for an initiator update event (use in slave to wait for master CT quark update notification)
inline void waitForInitiatorUpdate(const sc_time &timeout) const {wait(timeout, initiator_update_event);}
/// notify a CT master of a quark update
inline void notifyInitiatorUpdate() {initiator_update_event.notify();}
/// notify a CT master of a quark update
inline void notifyInitiatorUpdate(const sc_time &t) {initiator_update_event.notify(t);}
/// notify a CT master of a quark update
inline void notifyInitiatorUpdate(const double d, const sc_time_unit u) {initiator_update_event.notify(d,u);}
/// get the target update event (use in master to trigger on slave CT quark update notification)
inline const sc_event& getTargetUpdateEvent() const {return target_update_event;}
/// wait for a target update event (use in master to wait for slave CT quark update notification)
inline void waitForTargetUpdate(const sc_time &timeout) const {wait(timeout, target_update_event);}
};
/**
* Shared pointer type for GenericTransaction.
* Transaction containers always should be wrapped by a shared_ptr
* in order to avoid memory leakage.
*/
typedef boost::shared_ptr<GenericTransaction> GenericTransaction_P;
//---------------------------------------------------------------------------
/**
* Interface to access the generic transaction through the master.
* A master can get all attributes, but can set only master attributes.
*/
//---------------------------------------------------------------------------
class GenericMasterAccess
: protected virtual GenericTransaction
{
public:
using GenericTransaction::setMAddr;
using GenericTransaction::setMBurstLength;
using GenericTransaction::setMCmd;
using GenericTransaction::setMData;
using GenericTransaction::setMDataWidth;
using GenericTransaction::setMID;
using GenericTransaction::setMError;
using GenericTransaction::getMAddr;
using GenericTransaction::getMBurstLength;
using GenericTransaction::getSBurstLength;
using GenericTransaction::getMCmd;
using GenericTransaction::getMData;
using GenericTransaction::getMDataWidth;
using GenericTransaction::getSDataWidth;
using GenericTransaction::getMID;
using GenericTransaction::getSResp;
using GenericTransaction::getSData;
using GenericTransaction::getMError;
using GenericTransaction::getSError;
};
//---------------------------------------------------------------------------
/**
* Interface to access the generic transaction through the slave.
* A slave can get all attributes, but can set only slave attributes.
*/
//---------------------------------------------------------------------------
class GenericTargetAccess
: protected virtual GenericTransaction
{
public:
using GenericTransaction::setSBurstLength;
using GenericTransaction::setSData;
using GenericTransaction::setSDataWidth;
using GenericTransaction::setSResp;
using GenericTransaction::setSError;
using GenericTransaction::getMAddr;
using GenericTransaction::getMBurstLength;
using GenericTransaction::getSBurstLength;
using GenericTransaction::getMCmd;
using GenericTransaction::getMData;
using GenericTransaction::getMDataWidth;
using GenericTransaction::getSDataWidth;
using GenericTransaction::getMID;
using GenericTransaction::getSResp;
using GenericTransaction::getSData;
using GenericTransaction::getMError;
using GenericTransaction::getSError;
};
//---------------------------------------------------------------------------
/**
* Interface to access the generic transaction through the router.
* A router can only "see" the protocol attributes. It is not authorized
* to access the transaction data.
*/
//---------------------------------------------------------------------------
class GenericRouterAccess
: protected virtual GenericTransaction
{
public:
using GenericTransaction::getMID;
using GenericTransaction::getMCmd;
using GenericTransaction::getMAddr;
using GenericTransaction::getMBurstLength;
using GenericTransaction::getSBurstLength;
using GenericTransaction::getMDataWidth;
using GenericTransaction::getSDataWidth;
using GenericTransaction::getMError;
using GenericTransaction::getSError;
using GenericTransaction::setMDataWidth;
using GenericTransaction::setSDataWidth;
using GenericTransaction::setMError;
using GenericTransaction::setSError;
};
/**
* Helper function to get access to the transaction from an access handle.
*/
template <class T>
inline TRANSACTION_P _getTransactionAccess(T &a) {
boost::shared_ptr<void> im = boost::static_pointer_cast<void>(a); // simulate reinterpret_cast
return boost::static_pointer_cast<TRANSACTION>(im);
}
//---------------------------------------------------------------------------
/**
* This is the generic protocol API implementation.
* There are two methods available to schedule an atom on the GreenBus (i.e. start a phase):
* immediately, or delayed notification. Please note, that an
* immediate notification overwrites all prior immediate notifications
* that have been scheduled in the same delta cycle.
*/
//---------------------------------------------------------------------------
template <class PORT, class operation>
class Notifications
{
PORT& port;
public:
Notifications(PORT &port_) : port(port_) {}
typedef typename PORT::transaction transaction;
typedef typename PORT::transactionHandle transactionHandle;
typedef typename PORT::accessHandle accessHandle;
typedef typename PORT::phase phase;
void operator()(accessHandle th, phase _p, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p(_p);
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p));
GS_DELTA_WARNING;
}
void operator()(accessHandle th, phase _p, const sc_time &d, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p(_p);
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p),d);
}
void operator()(accessHandle th, phase _p, double d, sc_time_unit u, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p(_p);
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p),d,u);
}
void block(accessHandle th, phase _p, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p(_p);
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p));
port.wait(typename PORT::TRANSACTION_CONTAINER(t,p));
GS_DELTA_WARNING;
}
void block(accessHandle th, phase _p, const sc_time &d, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p(_p);
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p),d);
port.wait(typename PORT::TRANSACTION_CONTAINER(t,p));
}
void block(accessHandle th, phase _p, double d, sc_time_unit u, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p(_p);
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p,d),d,u);
port.wait(typename PORT::TRANSACTION_CONTAINER(t,p));
}
void operator()(accessHandle th, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p;
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p));
GS_DELTA_WARNING;
}
void operator()(accessHandle th , const sc_time &d, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p;
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p),d);
}
void operator()(accessHandle th , double d, sc_time_unit u, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p;
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t,p),d,u);
}
void block(accessHandle th, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p;
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t, p));
port.wait(typename PORT::TRANSACTION_CONTAINER(t,p));
GS_DELTA_WARNING;
}
void block(accessHandle th, const sc_time &d, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p;
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t, p),d);
port.wait(typename PORT::TRANSACTION_CONTAINER(t,p));
}
void block(accessHandle th, double d, sc_time_unit u, GenericSimulationModeType m=MODE_BA)
{
transactionHandle t = _getTransactionAccess(th);
operation p;
p.setSimulationMode(m);
port.out->notify(typename PORT::TRANSACTION_CONTAINER(t, p),d,u);
port.wait(typename PORT::TRANSACTION_CONTAINER(t,p));
}
};
// Functor to be used with Notifications
struct noChangePhase : public GenericPhase
{
noChangePhase( const GenericPhase & p) :GenericPhase(p.state,p.BurstNumber){ };
};
// Functor to be used with Notifications
struct IdlePhase : public GenericPhase
{
IdlePhase( const GenericPhase& p) :GenericPhase(GenericPhase::Idle){};
IdlePhase( ) :GenericPhase(GenericPhase::Idle){};
};
// Functor to be used with Notifications
struct setRequestValid_BurstNumber0Phase : public GenericPhase
{
setRequestValid_BurstNumber0Phase( const GenericPhase & p) : GenericPhase(GenericPhase::RequestValid,0) { };
setRequestValid_BurstNumber0Phase() : GenericPhase(GenericPhase::RequestValid,0) { };
};
// Functor to be used with Notifications
struct setRequestAcceptedPhase : public GenericPhase
{
setRequestAcceptedPhase(const GenericPhase & p) : GenericPhase(GenericPhase::RequestAccepted) { };
setRequestAcceptedPhase() : GenericPhase(GenericPhase::RequestAccepted) { };
};
// Functor to be used with Notifications
struct setRequestErrorPhase : public GenericPhase
{
setRequestErrorPhase(const GenericPhase & p) : GenericPhase(GenericPhase::RequestError) { };
setRequestErrorPhase() : GenericPhase(GenericPhase::RequestError) { };
};
// Functor to be used with Notifications
struct setDataValid_BurstUpdatePhase : public GenericPhase
{
setDataValid_BurstUpdatePhase(const GenericPhase & p) : GenericPhase(GenericPhase::DataValid, p.BurstNumber+1) { };
};
// Functor to be used with Notifications
struct setDataAcceptedPhase : public GenericPhase
{
setDataAcceptedPhase(const GenericPhase & p) : GenericPhase(GenericPhase::DataAccepted,p.BurstNumber) { };
};
// Functor to be used with Notifications
struct setDataErrorPhase : public GenericPhase
{
setDataErrorPhase(const GenericPhase & p) : GenericPhase(GenericPhase::DataError,p.BurstNumber) { };
};
// Functor to be used with Notifications
struct setResponseValidPhase : public GenericPhase
{
setResponseValidPhase(const GenericPhase & p) : GenericPhase(GenericPhase::ResponseValid) { };
setResponseValidPhase() : GenericPhase(GenericPhase::ResponseValid) { };
};
// Functor to be used with Notifications
struct setResponseAcceptedPhase : public GenericPhase
{
setResponseAcceptedPhase(const GenericPhase & p) : GenericPhase(GenericPhase::ResponseAccepted) { };
setResponseAcceptedPhase() : GenericPhase(GenericPhase::ResponseAccepted) { };
};
// Functor to be used with Notifications
struct setResponseErrorPhase : public GenericPhase
{
setResponseErrorPhase(const GenericPhase & p) : GenericPhase(GenericPhase::ResponseError) { };
setResponseErrorPhase() : GenericPhase(GenericPhase::ResponseError) { };
};
//---------------------------------------------------------------------------
/**
* The API for the generic protocol that can be accessed by the target port.
*/
//---------------------------------------------------------------------------
template <class PORT>
class GenericTargetAPI :
public PORT
{
public:
GenericTargetAPI ( sc_module_name port_name ) :
PORT ( port_name ),
Repass(*this),
Idle(*this),
AckRequest(*this),
ErrorRequest(*this),
AckData(*this),
ErrorData(*this),
Response(*this)
{}
/// hold current phase (no change)
Notifications<PORT, noChangePhase> Repass;
/// slave is idle, no active communication
Notifications<PORT, IdlePhase> Idle;
/// slave acknowledges a request atom
Notifications<PORT, setRequestAcceptedPhase> AckRequest;
/// slave replies an error to a request atom
Notifications<PORT, setRequestErrorPhase> ErrorRequest;
/// slave acknowledges data atom
Notifications<PORT, setDataAcceptedPhase> AckData;
/// slave replies an error to a data atom
Notifications<PORT, setDataErrorPhase> ErrorData;
/// slave sends a response atom
Notifications<PORT, setResponseValidPhase> Response;
};
//---------------------------------------------------------------------------
/**
* The generic slave port.
*/
//---------------------------------------------------------------------------
typedef GenericTargetAPI<slave_port<GenericTransaction,GenericTargetAccess,GenericPhase> > GenericSlavePort;
#define GenericTargetPort GenericSlavePort
//---------------------------------------------------------------------------
/**
* The API for the generic protocol that can be accessed by the initiator port.
*/
//---------------------------------------------------------------------------
template <class PORT>
class GenericInitiatorAPI :
public PORT
{
public:
typedef typename PORT::transactionHandle transactionHandle;
GenericInitiatorAPI ( sc_module_name port_name ) :
PORT ( port_name ),
Repass(*this),
Idle(*this),
Request(*this),
SendData(*this),
AckResponse(*this),
ErrorResponse(*this)
{}
/// hold current phase
Notifications<PORT, noChangePhase> Repass;
/// master is idle, no active communication
Notifications<PORT, IdlePhase> Idle;
/// master sends a request atom
Notifications<PORT, setRequestValid_BurstNumber0Phase> Request;
/// master sends a data atom
Notifications<PORT, setDataValid_BurstUpdatePhase> SendData;
/// master acknowledges a slave response
Notifications<PORT, setResponseAcceptedPhase> AckResponse;
/// master signals an error on a slave response
Notifications<PORT, setResponseErrorPhase> ErrorResponse;
typedef typename PORT::transaction transaction;
typedef typename PORT::accessHandle accessHandle;
typedef typename PORT::phase phase;
/**
* PV transact method. It is used in PV mode
* to send a whole transaction container at once.
* Please note that this method is blocking.
*/
inline void Transact(transactionHandle t) {
PORT::b_out->b_transact(t);
}
/// PV Transact method for access handle
inline void Transact(accessHandle a) {
Transact(_getTransactionAccess(a));
}
};
//---------------------------------------------------------------------------
/**
* The generic master initiator port.
*/
//---------------------------------------------------------------------------
typedef GenericInitiatorAPI<master_port<GenericTransaction,GenericMasterAccess,GenericPhase> > GenericMasterPort;
#define GenericInitiatorPort GenericMasterPort
//---------------------------------------------------------------------------
/**
* The generic router target multi-port.
*/
//---------------------------------------------------------------------------
typedef target_multi_port<GenericTransaction,GenericTargetAccess,GenericPhase> GenericRouterTargetPort;
//---------------------------------------------------------------------------
/**
* The generic router initiator multi-port.
*/
//---------------------------------------------------------------------------
typedef initiator_multi_port<GenericTransaction,GenericRouterAccess,GenericPhase> GenericRouterInitiatorPort;
See more files for this project here