Code Search for Developers
 
 
  

generic.h from GreenSocs at Krugle


Show generic.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 __GENERIC_H__
#define __GENERIC_H__

#include "gstlm/tlm.h"
#include "userAPI/basicPorts.h"
#include <stdarg.h>

#ifdef DUST_ENABLE 
# include "scv.h"
#endif



#ifdef GSVERBOSE
#define GS_DELTA_WARNING SC_REPORT_WARNING("GreenBus GenericAPI", "Using an untimed GreenBus notification. If you call this method multiple times while in the same delta cycle, only the last call will be processed. As a solution, use SC_ZERO_TIME delay.")
#else
#define GS_DELTA_WARNING
#endif

namespace tlm {
 

  //---------------------------------------------------------------------------
  /**
   * Interface to access the generic transaction through the master.
   */
  //---------------------------------------------------------------------------
  class GenericMasterAccess : public virtual TransactionBase {

  public :

    virtual void set_mID(const MID&) =0;
    virtual void set_mCmd(const MCmd&) =0;
    virtual void set_mAddr(const MAddr&) =0;
    virtual void set_mData(const MData&) =0;
    virtual void set_mBurstLength(const MBurstLength&) =0;

    virtual const MID& get_mID() const =0;
    virtual const MCmd& get_mCmd() const =0;
    virtual const MAddr& get_mAddr() const =0;
    virtual const MData& get_mData() const =0;
    virtual const MBurstLength& get_mBurstLength() const =0;

    virtual const SResp& get_sResp() const =0;
    virtual const MData& get_sData() const =0;

    virtual void set_mError(const Error& _mError)=0;
    virtual const Error get_mError() const=0;
    virtual const Error get_sError() const=0;

  };


  //---------------------------------------------------------------------------
  /**
   * Interface to access the generic transaction through the slave.
   */
  //---------------------------------------------------------------------------
  class GenericTargetAccess : public virtual TransactionBase {

  public :

    virtual void set_sResp(const SResp&) =0;
    virtual void set_sData(const MData&) =0;

    virtual const MID& get_mID() const =0;
    virtual const MCmd& get_mCmd() const =0;
    virtual const MAddr& get_mAddr() const =0;
    virtual const MData& get_mData() const =0;
    virtual void get_mData(const MData & _dst ) =0;
    virtual const MBurstLength& get_mBurstLength() const =0;

    virtual const SResp& get_sResp() const =0;
    virtual const MData& get_sData() const =0;

    virtual const Error get_mError() const=0;
    virtual void set_sError(const Error& _sError)=0;
    virtual const Error get_sError() const=0;
    
  };

  //---------------------------------------------------------------------------
  /**
   * Interface to access the generic transaction through the router.
   */
  //---------------------------------------------------------------------------
  class GenericRouterAccess : public virtual TransactionBase {

  public :

    virtual const MID& get_mID() const =0;
    virtual const MCmd& get_mCmd() const =0;
    virtual const MAddr& get_mAddr() const =0;
    virtual const MBurstLength& get_mBurstLength() const =0;

    virtual void set_mError(const Error& _mError)=0;
    virtual const Error get_mError() const=0;
    virtual void set_sError(const Error& _sError)=0;
    virtual const Error get_sError() const=0;

  };

  //---------------------------------------------------------------------------
  /**
   * A generic phase class
   */
  //---------------------------------------------------------------------------
  char phase_desc[] = "Phases for the Generic Protocol";
  class GenericPhase : public Description<phase_desc>
  {

  public:

    enum {
      Idle = 0,
      RequestValid,RequestAccepted,RequestError,
      DataValid, DataAccepted, DataError,
      ResponseValid,ResponseAccepted, ResponseError,
      LAST_GENERIC_PHASE
    };

    int state;

    unsigned int BurstNumber;

    GenericPhase() : state(Idle) {};
    GenericPhase(int s):state(s){BurstNumber=0;};
    GenericPhase(int s, unsigned int b):state(s),BurstNumber(b){};

    inline bool isRequestValid() { return state == RequestValid; }
    inline bool isRequestAccepted() { return state == RequestAccepted; }
    inline bool isRequestError() { return state == RequestError; }
    inline bool isDataValid() { return state == DataValid; }
    inline bool isDataAccepted() { return state == DataAccepted; }
    inline bool isDataError() { return state == DataError; }
    inline bool isResponseValid() { return state == ResponseValid; }
    inline bool isResponseAccepted() { return state == ResponseAccepted; }
    inline bool isResponseError() { return state == ResponseError; }

    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 return std::string("unknown phase");
    }
  };


  //---------------------------------------------------------------------------
  /**
   * A generic transaction class
   */
  //---------------------------------------------------------------------------
  
  #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.set_name(#name)

  #define ADDTOPHASE(name, ...) \
    set_phases(name, false, __VA_ARGS__ , 65563 )

  #define ADDEXTTOPHASE(name, ...) \
    set_phases(name, true, __VA_ARGS__ , 65563 )
  
  class GenericTransaction :
    public virtual GenericMasterAccess,
    public virtual GenericTargetAccess,
    public virtual GenericRouterAccess
  {

#ifdef DUST_ENABLE
    friend class scv_extensions<GenericTransaction>;
#endif

 protected:
    MCmd mCmd;
    MAddr mAddr;
    MData msData;
    MBurstLength mBurstLength;
    SResp sResp;
    Error mError;
    Error sError;
    
    MID mID;

    bool is_extended;
    std::string extendedType;
    attribute_map attribs;
    attribute_map extended_attribs;
    
  public:

    void set_mID(const MID& _mID) {mID=_mID;}
    void set_mCmd(const MCmd& _mCmd){mCmd=_mCmd;}
    void set_mAddr(const MAddr& _mAddr){ mAddr=_mAddr;}
    void set_mData(const MasterDataType& _mData){ msData.set(_mData);}
        
    void set_mBurstLength(const MBurstLength& _mBurstLength){  mBurstLength=_mBurstLength; }
    void set_sResp(const SResp& _sResp){ sResp = _sResp; }
    void set_sData(const MData& _sData){ msData.deepcopy_to( _sData ); }
    // todo sData for "slices"

    const MID& get_mID() const {return mID;}
    const MCmd& get_mCmd() const {return mCmd; }
    const MAddr& get_mAddr() const {return mAddr; }
    const MData& get_mData() const {return msData; }
    void get_mData(const MData & _dst ) { msData.deepcopy_from(_dst); }
    // todo mData for "slices"
    
    const MBurstLength& get_mBurstLength() const {return mBurstLength; }
    const SResp& get_sResp() const {return sResp; }
    const MData& get_sData() const {return msData; }

    void set_mError(const Error& _mError) {mError=_mError;}
    const Error get_mError() const {return mError;}
    void set_sError(const Error& _sError) {sError=_sError;}
    const Error get_sError() const {return sError;}
    
    
    //access functions
    attribute_iterator get_AttributeIterator(int phase){return attribs.find(phase);}
    attribute_iterator lastAttribute(int phase){ 
      if (attribs.find(phase)==attribs.end()) 
        return attribs.end() ;
      else 
        return attribs.upper_bound(phase);
      }

    attribute_iterator get_ExtendedAttributeIterator(int phase){return extended_attribs.find(phase);}
    attribute_iterator lastExtendedAttribute(int phase){
      if (extended_attribs.find(phase)==extended_attribs.end()) 
        return extended_attribs.end() ;
      else 
        return extended_attribs.upper_bound(phase);
    }
    
    void set_phases(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);
    }
        
    bool isExtended(){return is_extended;}
    std::string getExtendedType(){return extendedType;}
    
  GenericTransaction() : mBurstLength(1), mError(0), sError(0),is_extended(false), extendedType("N/A") {
    INITATTRIBUTE(mCmd);
    ADDTOPHASE(mCmd,REQUESTPHASE);
    INITATTRIBUTE(mAddr);
    ADDTOPHASE(mAddr,REQUESTPHASE, DATAPHASE, RESPONSEPHASE);    
    INITATTRIBUTE(msData);    
    ADDTOPHASE(msData,DATAPHASE, RESPONSEPHASE);    
    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);        
    }
  };

  typedef boost::shared_ptr<GenericTransaction> GenericTransaction_P;

  //---------------------------------------------------------------------------
  /**
   * Generic API to notify with three methods: now, sc_time, double+sc_time_unit
   */
  //---------------------------------------------------------------------------
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::phaseHandle phaseHandle;

    void operator()(accessHandle th, phaseHandle _p)
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p(_p);
      port.out->notify(typename PORT::pair_type(t,p));
      GS_DELTA_WARNING;
    }

    void operator()(accessHandle th, phaseHandle _p, const sc_time &d)
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p(_p);
      port.out->notify(typename PORT::pair_type(t,p),d);
    }

    void operator()(accessHandle th, phaseHandle _p, double d, sc_time_unit u)
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p(_p);
      port.out->notify(typename PORT::pair_type(t,p),d,u);
    }

    void block(accessHandle th, phaseHandle _p) 
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p(_p);
      port.out->notify(typename PORT::pair_type(t,p));
      port.wait(typename PORT::pair_type(t,p));
      GS_DELTA_WARNING;
    }
    
    void block(accessHandle th, phaseHandle _p, const sc_time &d) 
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p(_p);
      port.out->notify(typename PORT::pair_type(t,p),d);
      port.wait(typename PORT::pair_type(t,p));
    }

    void block(accessHandle th, phaseHandle _p, double d, sc_time_unit u) 
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p(_p);
      port.out->notify(typename PORT::pair_type(t,p,d),d,u);
      port.wait(typename PORT::pair_type(t,p));
    }

    void operator()(accessHandle th)
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p;
      port.out->notify(typename PORT::pair_type(t,p));
      GS_DELTA_WARNING;
    }

    void operator()(accessHandle th , const sc_time &d)
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p;
      port.out->notify(typename PORT::pair_type(t,p),d);
    }

    void operator()(accessHandle th , double d, sc_time_unit u)
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p;
      port.out->notify(typename PORT::pair_type(t,p),d,u);
    }

    void block(accessHandle th) 
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p;
      port.out->notify(typename PORT::pair_type(t, p));
      port.wait(typename PORT::pair_type(t,p));
      GS_DELTA_WARNING;
    }

    void block(accessHandle th, const sc_time &d) 
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p;
      port.out->notify(typename PORT::pair_type(t, p),d);
      port.wait(typename PORT::pair_type(t,p));
    }

    void block(accessHandle th, double d, sc_time_unit u) 
    {
      transactionHandle t = boost::dynamic_pointer_cast<transaction>(th);
      operation p;
      port.out->notify(typename PORT::pair_type(t, p),d,u);
      port.wait(typename PORT::pair_type(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 initiator port.
   */
  //---------------------------------------------------------------------------
  template <class PORT>
  class GenericInitiatorAPI :
    public PORT
  {

  public:

    GenericInitiatorAPI ( sc_module_name port_name ) :
      PORT ( port_name ),
      Repass(*this),
      Idle(*this),
      Request(*this),
      SendData(*this),
      AckData(*this),
      ErrorData(*this),
      AckResponse(*this),
      ErrorResponse(*this)
    {}

    Notifications<PORT, noChangePhase>                     Repass;
    Notifications<PORT, IdlePhase>                         Idle;
    Notifications<PORT, setRequestValid_BurstNumber0Phase> Request;
    Notifications<PORT, setDataValid_BurstUpdatePhase>     SendData;
    Notifications<PORT, setDataAcceptedPhase>              AckData;
    Notifications<PORT, setDataErrorPhase>                 ErrorData;
    Notifications<PORT, setResponseAcceptedPhase>          AckResponse;
    Notifications<PORT, setResponseErrorPhase>             ErrorResponse;


    //TODO: This Transact have to go away!

    typedef typename PORT::transaction transaction;
    typedef typename PORT::accessHandle accessHandle;
    typedef typename PORT::phaseHandle phaseHandle;

    void Transact(accessHandle t)
    {
      PORT::b_out->b_transact(boost::dynamic_pointer_cast<transaction>(t)); 
      // cast from base class ACCESS to derived class TRANSACTION
    }

  };

  
  //---------------------------------------------------------------------------
  /**
   * 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),
      FinishBlocking(*this),
      SendData(*this),
      AckData(*this),
      ErrorData(*this),
      Response(*this),
      AckRequest(*this),
      ErrorRequest(*this)
    {}

    Notifications<PORT, noChangePhase>            Repass;
    Notifications<PORT, IdlePhase>                Idle;
    Notifications<PORT, setRequestAcceptedPhase>  FinishBlocking;
    Notifications<PORT, setDataValid_BurstUpdatePhase>        SendData;
    Notifications<PORT, setDataAcceptedPhase>     AckData;
    Notifications<PORT, setDataErrorPhase>        ErrorData;
    Notifications<PORT, setResponseValidPhase>    Response;
    Notifications<PORT, setRequestAcceptedPhase>  AckRequest;
    Notifications<PORT, setRequestErrorPhase>     ErrorRequest;
  };


  //---------------------------------------------------------------------------
  /**
   * The default master initiator port.
   */
  //---------------------------------------------------------------------------
  typedef GenericInitiatorAPI<master_port<GenericTransaction,GenericMasterAccess,GenericPhase> > GenericMasterPort;


  //---------------------------------------------------------------------------
  /**
   * The default router initiator port.
   */
  //---------------------------------------------------------------------------
  typedef GenericInitiatorAPI<initiator_port<GenericTransaction,GenericRouterAccess,GenericPhase> > GenericRouterPort;


  //---------------------------------------------------------------------------
  /**
   * The default slave and router target port.
   */
  //---------------------------------------------------------------------------
  typedef GenericTargetAPI<target_port<GenericTransaction,GenericTargetAccess,GenericPhase> > GenericTargetPort;
  
  //---------------------------------------------------------------------------
  /**
   * Low level router multi-ports.
   */
  //---------------------------------------------------------------------------
  typedef target_multi_port<GenericTransaction,GenericTargetAccess,GenericPhase> GenericRouterTargetPort;
  typedef initiator_multi_port<GenericTransaction,GenericRouterAccess,GenericPhase>  GenericRouterInitiatorPort;


} // end of namespace tlm


#endif




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