Code Search for Developers
 
 
  

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

GreenSocs

To develop SystemC infrustructure, basic IP, patches and add on library code for eventual standerdization.\r\nThe GreenSocs project is made up of a number of contributions (sub projects). Please visit www.greensocs.com for more information.

Project homepage: http://sourceforge.net/projects/greensocs
Programming language(s): C,C++,Java,Perl,XML
License: other

  PLB.h
  generic.dynamic_casts.h
  generic.h
  generic.static_casts.h
  generic2.h
  splitcomplete.h