Code Search for Developers
 
 
  

shipAPI.h from GreenSocs at Krugle


Show shipAPI.h syntax highlighted

/*
Copyright (c) 2006 : Technical University of Braunschweig, Germany

All rights reserved.

Authors: Robert Guenzel, Wolfgang Klingauf, TU Braunschweig, E.I.S.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.  Redistributions
in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.  Neither the name of
the Technical University of Braunschweig, Germany nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#ifndef __shipAPI_h__
#define __shipAPI_h__

                                                       //#define VERBOSE

#include <systemc.h>
#include "gstlm/tlm_slave_if.h"
#include "protocol/generic.h"

using namespace tlm;


///
//---------------------------------------------------------------------------
/**
 * This is an abstract class from which objects must inherit to be 
 * SHIP-transferrable.
 */
//---------------------------------------------------------------------------
class ship_serializable_if
{
   public:

   /// Serialize the data content of a SHIP object that inherits from ship_serializable_if.
   /**
    * This method has to be implemented by any SHIP object and 
    * must return a reference to an array of sc_uint<64> 
    * values that contain a serialized data representation of 
    * the content of the SHIP object.
    * 
    * @return Returns the reference to an array of sc_uint<64> values. 
    */
   virtual sc_uint<64> * serialize() = 0;

   /// Deserialize the data content of a SHIP object that inherits from ship_serializable_if.
   /**
    * This method has to be implemented by any SHIP object.
    * Its purpose is to read a serial data stream which was 
    * generated by the serialize method, and to copy the content
    * of this data stream into the corresponding data fields
    * of the SHIP object.
    * 
    * @param values An array of sc_uint<64> objects has to be passed
    *               which contains the data values that are to be deserialized.
    *               The deserialize method reads those data values and
    *               maps them to the SHIP object's internal data structure.
    * @param length Number of 64 bit values that are passed.
    * @return The number of 64 bit values that were successfully processed.
    */
   virtual unsigned int deserialize(sc_uint<64> *values, unsigned int length)=0;

   /// Return the size of the serialized object
   /**
    * @return The return value has to reflect the size of
    *         the data array which is generated by the serialize
    *         method. The returned value has to be 64 bit aligned. 
    *         Thus, if the SHIP object for example needs a buffer 
    *         of four sc_uint<64> values to store its serial data
    *         representation, the getSerialLength method should 
    *         return 4.
    */
   virtual unsigned int getSerialLength()=0;
     
};



//---------------------------------------------------------------------------
/**
 * SHIP command definitions 
 * @see shipSlaveAPI.waitEvent()
 */
//---------------------------------------------------------------------------
///The enum for the available commands in the SHIP-system
enum ship_command_enum {
  ///A master requests data from a slave
  SHIP_REQUEST, 
  ///A master sends data to a slave
  SHIP_SEND, 
  ///No active command available
  SHIP_NONE
};

///This struct is returned by the waitEvent method. 
/**
 * @see ship_slave_if.waitEvent()
 */
struct ship_command {
  ///The actual command of this ship-command
  /**
   * @see command
   */
  ship_command_enum cmd;

  ///The burstlength of the current command.
  /**
   * This burstlength information may be necessary when 
   * the serialisation length isn't fixed
   */
  int burstlength;
};



//---------------------------------------------------------------------------
/**
 * SHIP master API implementation based on the GreenBus TLM fabric.
 */
//---------------------------------------------------------------------------
template <class T>
class shipMasterAPI
: public GenericMasterPort
{  
public:
  typedef GenericMasterPort PORT;

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

  SC_HAS_PROCESS(shipMasterAPI);

  shipMasterAPI ( sc_module_name port_name, bool pvtmode = false ) : 
    PORT(port_name),
    mAddr(0x0),
    mPVT(pvtmode)    
  {
    // DUST structure analysis
    #ifdef DUST_ENABLE
    DUST_MASTER_PORT("ShipMasterAPI", "SHIP");
    #endif

    SC_METHOD(react); // handle PVT protocol
    sensitive << PORT::default_event();
    dont_initialize();

    mCmd.cmd = SHIP_NONE;
  }
 
  shipMasterAPI ( sc_module_name port_name, MAddr target_addr, bool pvtmode = false ) :
    PORT(port_name),    
    mAddr(target_addr),
    mPVT(pvtmode)
  {
    // DUST structure analysis
    #ifdef DUST_ENABLE    
    DUST_MASTER_PORT("ShipMasterAPI", "SHIP");
    #endif
    SC_METHOD(react);
    sensitive << PORT::default_event();
    dont_initialize();

    mCmd.cmd = SHIP_NONE;
  }
 
  
  /// Send a SHIP object to a slave
  /**
   * The send method sends a SHIP object to a SHIP slave.
   * Communication using this method is blocking, thus 
   * it will not return until the SHIP object has been 
   * completely delivered to the slave.
   *
   * @param obj The object to be send.
   */
  void send( T& obj ) {
    accessHandle ah = PORT::create_transaction();

    ah->set_mCmd(Generic_MCMD_WR);
    ah->set_mAddr(mAddr);

    unsigned int objbytes = obj.getSerialLength()*8;
    mCmd.cmd = SHIP_SEND;
    mCmd.burstlength = objbytes/8;

    if (!mPVT) { // PV bypass mode 
      ah->set_mBurstLength(sizeof(T*)); // only 32 bit pointer to SHIP object
      ah->set_mData(MasterDataType((unsigned char*)&obj, sizeof(T*)));
      transactionHandle th = boost::dynamic_pointer_cast<transaction>(ah);
      GS_TRACE(name(), "send() calls PV b_transact.");
      PORT::Transact(th);
      mCmd.cmd = SHIP_NONE;
    }

    else { // PVT transaction
      sc_uint<64> *objdata = obj.serialize();
      ah->set_mBurstLength(objbytes); // serial length is 64 bit aligned

      unsigned char *data = new unsigned char[objbytes];
      
      // copy serialized SHIP object to a temporal char array
      for (unsigned int i=0, j=0; i<objbytes; i+=8, j++) {
        data[i]   = objdata[j](63,56);
        data[i+1] = objdata[j](55,48);
        data[i+2] = objdata[j](47,40);
        data[i+3] = objdata[j](39,32);
        data[i+4] = objdata[j](31,24);
        data[i+5] = objdata[j](23,16);
        data[i+6] = objdata[j](15,8);
        data[i+7] = objdata[j](7,0);
      }
      
      ah->set_mData(MasterDataType(data, objbytes));
      
      transactionHandle th = boost::dynamic_pointer_cast<transaction>(ah);
      phaseHandle phase;
      
      // PVT request phase
      GS_TRACE(name(), "send() starts request phase.");
      PORT::Request.block(th);

      phase = PORT::get_phase();
      if (phase.state == GenericPhase::RequestAccepted) {        
        GS_TRACE(name(), "send() request has been accepted by the slave.");
      } else {
        SC_REPORT_ERROR(name(), "Master request was not acknowledged by the slave - something went wrong.");
        mCmd.cmd = SHIP_NONE;
        return;
      }

      // PVT data phase
      PORT::SendData.block(th, phase);
      phase = PORT::get_phase();
      if (phase.state == GenericPhase::DataAccepted) {
        GS_TRACE(name(), "send() data has been accepted by the slave.");
      } else {
        SC_REPORT_ERROR(name(), "send() our data was not accepted by the slave - something went wrong.");
      }

      mCmd.cmd = SHIP_NONE;
      delete[] data;
    }
  }


  /// Request a SHIP object from a slave
  /**
   * The request method requests a SHIP object from a SHIP slave.
   * Communication using this method is blocking, thus the request
   * method will not return unless the SHIP object
   * has been completely received.
   * @param obj A reference to an SHIP object, into which 
   *            the requested data will be copied.
   */
  void request( T& obj ) {
    sc_assert(mCmd.cmd == SHIP_NONE);

    accessHandle ah = PORT::create_transaction();

    ah->set_mCmd(Generic_MCMD_RD);
    ah->set_mAddr(mAddr);
    ah->set_mBurstLength(0); // empty request

    mCmd.cmd = SHIP_REQUEST;

    transactionHandle th = boost::dynamic_pointer_cast<transaction>(ah);
    phaseHandle phase;

    if (!mPVT) { // PV bypass mode 
      GS_TRACE(name(), "request() calls PV b_transact.");
      PORT::Transact(th);
      
      // now lets look what we have received
      sc_assert(th->get_mBurstLength() == sizeof(T*));
      
      MasterDataType data;
      data.set(th->get_mData());
      T *robj = ((T*)&data[0]);
      
      obj = *robj; // copy received SHIP object to master
    }
    else { // PVT mode
      GS_TRACE(name(), "request() starts request phase.");
      PORT::Request.block(th);

      phase = PORT::get_phase();
      if (phase.state == GenericPhase::RequestAccepted) {
        GS_TRACE(name(), "request() our request has been accepted by the slave.");
      } else {
        SC_REPORT_ERROR(name(), "request() master request was not acknowledged by the slave - something went wrong.");
        mCmd.cmd = SHIP_NONE;
        return;
      }

      // now wait for slave response (will be received by react method)
      sc_core::wait(mResponseEvent);

      MasterDataType data;
      data.set(th->get_mData());
      sc_uint<64> *objdata = new sc_uint<64>[(int)(data.byte_size()/8)];
    
      for (unsigned int i=0, j=0; i<data.byte_size(); i+=8, j++) {
        objdata[j](63,56) = data[i];
        objdata[j](55,48) = data[i+1];
        objdata[j](47,40) = data[i+2];
        objdata[j](39,32) = data[i+3];
        objdata[j](31,24) = data[i+4];
        objdata[j](23,16) = data[i+5];
        objdata[j](15,8)  = data[i+6];
        objdata[j](7,0)   = data[i+7];
      }
    
      obj.deserialize(objdata, data.byte_size()/8);
      delete[] objdata;

      // we are done -> send ResponseACK
      // TODO: remove SC_ZERO_TIME parameter (move it into generic.h)
      PORT::AckResponse(ah, phase, SC_ZERO_TIME);

      GS_TRACE(name(), "request() received slave response OK.");
    }

    mCmd.cmd = SHIP_NONE;
  }


  /// Wrapper for bind operator
  void operator() (tlm_port<b_if_type,if_type>& other) {
    PORT::operator()(other);
  }

  /// Wrapper for bind operator
  void operator() (tlm_multi_port<b_if_type,if_type>& other) {
    PORT::operator()(other);
  }

  void operator() (tlm_port_forwarder_base<b_if_type,if_type>& other) {
    PORT::operator()(other);
  }

protected:
  /**
   * Play the PVT protocol with the slave
   */
  void react() {
    accessHandle ah = PORT::get_transactionHandle();
    phaseHandle ph = PORT::get_phase();
    PVTProcess(ah, ph);
  }

  void PVTProcess(accessHandle ah, phaseHandle ph) { 
    switch (ph.state) {
    case GenericPhase::ResponseValid: // slave sends response
      {
        mCmd.burstlength = ah->get_mBurstLength()/8;
        GS_TRACE(name(), "react() received slave response (a SHIP object).");
        
        // notify request() method
        mResponseEvent.notify();
      }
      break;

    default:
      break; // do nothing
    }
  }


protected:
  /// Address range of this SHIP port
  MAddr mAddr;
  /// Use PVT transfer mode?
  bool mPVT;
  /// The current SHIP command
  ship_command mCmd;
  /// Internal notification
  sc_event mResponseEvent;

};
  


//---------------------------------------------------------------------------
/**
 * SHIP slave API implementation based on the GreenBus TLM fabric.
 */
//---------------------------------------------------------------------------
template <class T>
class shipSlaveAPI
: public GenericTargetPort,
  public tlm_b_if<GenericTransaction_P>,
  public tlm_slave_if<MAddr>
{     
public:
  typedef GenericTargetPort PORT;
  typedef typename PORT::transaction transaction;
  typedef typename PORT::transactionHandle transactionHandle;
  typedef typename PORT::accessHandle accessHandle;
  typedef typename PORT::phaseHandle phaseHandle;

  SC_HAS_PROCESS(shipSlaveAPI);

  shipSlaveAPI ( sc_module_name port_name, bool pvtmode = false ) : 
    PORT(port_name),    
    mBaseAddr(0x0),
    mHighAddr(0x0),
    mPVT(pvtmode),
    mReplyObj(NULL)
  {
    // DUST structure analysis
    #ifdef DUST_ENABLE    
    DUST_SLAVE_PORT("ShipSlaveAPI", "SHIP");
    #endif

    PORT::bind_b_if(*this); 

    SC_METHOD(react); // this method handles the PVT protocol
    sensitive << PORT::default_event();
    dont_initialize();

    mCmd.cmd = SHIP_NONE;
    mCmd.burstlength = 0;
  }

  shipSlaveAPI ( sc_module_name port_name, MAddr base_addr, MAddr high_addr, bool pvtmode = false ) :
    PORT(port_name),    
    mBaseAddr(base_addr),
    mHighAddr(high_addr),
    mPVT(pvtmode),
    mReplyObj(NULL)
  {
    // DUST structure analysis
    #ifdef DUST_ENABLE    
    DUST_SLAVE_PORT("ShipSlaveAPI", "SHIP");
    #endif

    PORT::bind_b_if(*this); 

    SC_METHOD(react); // this method handles the PVT protocol
    sensitive << PORT::default_event();
    dont_initialize();

    mCmd.cmd = SHIP_NONE;
    mCmd.burstlength = 0;
  }
  
  /// Receive a SHIP object from a master 
  /**
   * The recv method copies the last received
   * SHIP object into a user SHIP object.
   * @param obj A reference to a SHIP object. The received
   *            object will be copied into this object.
   */
  void recv(T& obj) {
    if (mCmd.cmd != SHIP_SEND) {
      SC_REPORT_ERROR(name(), "recv() called, but not in RECV state");
      return;
    }

    if (!mPVT) {  // PV mode
      // we received a pointer to the master's SHIP object, 
      // so do a direct copy
      obj = *mObj;
      mTransactEvent.notify(); // notify b_transact
    }
    else {  // PVT mode
      accessHandle ah = PORT::get_transactionHandle();
      phaseHandle ph = PORT::get_phase();    

      // we received an array of PVT data quarks, 
      // so deserialize them to the slave's SHIP object
      MasterDataType data;
      data.set(ah->get_mData());
      sc_uint<64> *objdata = new sc_uint<64>[(int)(data.byte_size()/8)];
    
      for (unsigned int i=0, j=0; i<data.byte_size(); i+=8, j++) {
        objdata[j](63,56) = data[i];
        objdata[j](55,48) = data[i+1];
        objdata[j](47,40) = data[i+2];
        objdata[j](39,32) = data[i+3];
        objdata[j](31,24) = data[i+4];
        objdata[j](23,16) = data[i+5];
        objdata[j](15,8)  = data[i+6];
        objdata[j](7,0)   = data[i+7];
      }
    
      obj.deserialize(objdata, data.byte_size()/8);
      delete[] objdata;

      // send DataACK
      // TODO: remove SC_ZERO_TIME parameter (move it into generic.h)
      PORT::AckData(ah, ph, SC_ZERO_TIME);
    }

    mCmd.cmd = SHIP_NONE; // idle again    

    GS_TRACE(name(), "recv() delivered a SHIP object.");
  }
  

  /// Send a SHIP object to a master in answer to a request
  /**
   * The reply method sends a SHIP object to a master 
   * in answer to a SHIP request.
   * @param obj The object to send to the master.
   */
  void reply(T& obj) {
    mCmd.burstlength = obj.getSerialLength();

    if (!mPVT) { // PV bypass mode 
      sc_assert(mRequestHandle != NULL);

      // create local copy of reply data
      if (mReplyObj != NULL)
        delete mReplyObj;
      mReplyObj = new T();
      *mReplyObj = obj;

      mRequestHandle->set_mBurstLength(sizeof(T*)); // only one complex data object
      mRequestHandle->set_mData(MasterDataType((unsigned char*)mReplyObj, sizeof(T*)));
      GS_TRACE(name(), "reply() copied SHIP object to transaction container.");
      mCmd.cmd = SHIP_NONE;
      mTransactEvent.notify(); // notify b_transact      
    }

    else { // PVT transaction
      accessHandle ah = PORT::get_transactionHandle();
      transactionHandle th = boost::dynamic_pointer_cast<transaction>(ah);
      phaseHandle phase;

      unsigned int objbytes = obj.getSerialLength()*8;
      sc_uint<64> *objdata = obj.serialize();
      th->set_mBurstLength(objbytes); // serial length is 64 bit aligned

      unsigned char *data = new unsigned char[objbytes];
      
      // copy serialized SHIP object to a temporal char array
      for (unsigned int i=0, j=0; i<objbytes; i+=8, j++) {
        data[i]   = objdata[j](63,56);
        data[i+1] = objdata[j](55,48);
        data[i+2] = objdata[j](47,40);
        data[i+3] = objdata[j](39,32);
        data[i+4] = objdata[j](31,24);
        data[i+5] = objdata[j](23,16);
        data[i+6] = objdata[j](15,8);
        data[i+7] = objdata[j](7,0);
      }

      th->set_mData(MasterDataType(data, objbytes));
      
      // PVT response phase
      GS_TRACE(name(), "reply() starts response phase.");
      PORT::Response.block(th);
      delete data;
      
      phase = PORT::get_phase();
      if (phase.state == GenericPhase::ResponseAccepted) {
        GS_TRACE(name(), "reply() response has been accepted by the master.");
      } else {
        SC_REPORT_ERROR(name(), "reply() response was not acknowledged by the master - something went wrong.");
      }

      mCmd.cmd = SHIP_NONE;
    }
  }

  
  /// Wait for commands from a master
  /**
   * For each SHIP slave port, a SC_THREAD has to be implemented
   * which handles commands from the SHIP master connected
   * to this slave port. This can be performed by calling the
   * waitEvent method, which does not return unless a SHIP command
   * has been received. 
   * 
   * A typical implementation would look like this:
   * <pre>
   * ship_command comm;
   * while(1) {
   *   comm = slave_port->waitEvent();
   *   switch(comm.cmd) {
   *     case SHIP_SEND:
   *       // receive data using slave_port->recv(...)
   *       break;
   *     case SHIP_REQUEST:
   *       // send data using slave_port->reply(...)
   *       break;
   *     default:
   *       cout << "Unknown ship_command: " << comm.cmd << endl;
   *   }
   * }
   * </pre>
   * 
   * @return The return value is a ship_command-structure.
   * @see ship_command
   */
  ship_command waitEvent() {
    if (mCmd.cmd != SHIP_NONE) // return immediately if we are inside a transaction
      return mCmd;
    else {  
      do {  // wait for something to happen        
        sc_core::wait(mEvent); 
      } while(mCmd.cmd == SHIP_NONE);
      return mCmd;
    }
  }

  
  /**
   * Play the PVT protocol with the master.
   */
  void react() {
    accessHandle ah = PORT::get_transactionHandle();
    phaseHandle ph = PORT::get_phase();
    PVTProcess(ah, ph);
  }

  void PVTProcess(accessHandle ah, phaseHandle ph) {    
    switch (ph.state) {
    case GenericPhase::RequestValid: // master sends request
      {
        if (mCmd.cmd != SHIP_NONE) {
          SC_REPORT_ERROR(name(), "react() got request, but is already handling another transaction. Split transactions are not allowed with SHIP.");
        }
        else {
          // TODO: remove SC_ZERO_TIME parameter (move it into generic.h)
          PORT::AckRequest(ah, ph, SC_ZERO_TIME); // immediate ACK
          
          if (ah->get_mCmd() == Generic_MCMD_WR) {
            GS_TRACE(name(), "react() accepted SEND request. Now waiting for data.");
            mCmd.cmd = SHIP_SEND;
          }
          else if (ah->get_mCmd() == Generic_MCMD_RD) {
            GS_TRACE(name(), "react() accepted REQUEST request. Now waiting for slave to call reply().");
            mCmd.cmd = SHIP_REQUEST;
            mEvent.notify();
          }
          else {
            SC_REPORT_ERROR(name(), "react() got unknown request. Ignoring.");
          }
        }
      }
      break;

    case GenericPhase::DataAccepted: // master acknowledges data (should this happen??)
      {
        GS_TRACE(name(), "react() got dataAccepted. This should not happen!? (slave uses response phase!)");
      }
      break;

    case GenericPhase::DataValid: // master sends data
      {
        mCmd.burstlength = ah->get_mBurstLength()/8;
        GS_TRACE(name(), "react() received a SHIP object. Now waiting for slave to call recv().");

        // notify waitEvent() method
        mEvent.notify();
      }
      break;


    case GenericPhase::ResponseAccepted: // master acknowledges response
      {
        GS_TRACE(name(), "react() got responseAccepted. Transaction finished OK.");
      }
      break;

    default:
      {
        SC_REPORT_ERROR(name(), "react() got triggered with unexpected phase.");
      }
    }
  }


  /**
   * The tlm_b_if PV transaction implementation
   */
  virtual void b_transact(transactionHandle th) {
    sc_assert(mCmd.cmd == SHIP_NONE);

    if (th->get_mCmd() == Generic_MCMD_WR) { // master sends data
      MasterDataType data;
      data.set(th->get_mData());
      mObj = ((T*)&data[0]);
      
      mCmd.cmd = SHIP_SEND;
      mCmd.burstlength = mObj->getSerialLength();     
      
      GS_TRACE(name(), "b_transact() PV-received a SHIP object. Now waiting for slave to call recv().");

      // notify waitEvent method
      mEvent.notify();

      // wait for finalization of this request by the slave
      sc_core::wait(mTransactEvent);
    }

    else if (th->get_mCmd() == Generic_MCMD_RD) { // master requests data
      mCmd.cmd = SHIP_REQUEST;
      mCmd.burstlength = th->get_mBurstLength();

      // save request handle in class member
      mRequestHandle = th;

      GS_TRACE(name(), "b_transact() PV-received a SHIP request. Now waiting for slave to call request().");

      // notify waitEvent method
      mEvent.notify();

      // wait for finalization of this request by the slave
      sc_core::wait(mTransactEvent);
    }
  }


  /**
   * The tlm_slave_if set address function.
   */
  virtual void setAddress(MAddr base, MAddr high) {
    mBaseAddr = base;
    mHighAddr = high;
  }

  /**
   * The tlm_slave_if get address function.
   */
  virtual void getAddress(MAddr& base, MAddr& high) {
    base = mBaseAddr;
    high = mHighAddr;
  }

  void operator() (tlm_port_forwarder_base<b_if_type,if_type>& other) {
    PORT::operator()(other);
  }

  
protected:
  /// Address range of this SHIP port
  MAddr mBaseAddr, mHighAddr;
  /// Use PVT transfer mode?
  bool mPVT;
  /// The current ship object
  T *mObj, *mReplyObj;
  /// State change event
  sc_event mEvent, mTransactEvent;
  /// The current state
  ship_command mCmd;
  /// Handle to the current PV request
  transactionHandle mRequestHandle;

};

template <class T>
class shipMasterAPIForward: public basic_port_forwarder<shipMasterAPI<T>, shipSlaveAPI<T>, GenericTransaction, GenericPhase> {
    public:
      shipMasterAPIForward(sc_module_name name): basic_port_forwarder<shipMasterAPI<T>, shipSlaveAPI<T>, GenericTransaction, GenericPhase>(name){}
};

template <class T>
class shipSlaveAPIForward: public basic_port_forwarder<shipSlaveAPI<T>, shipMasterAPI<T>, GenericTransaction, GenericPhase> {
    public:
      shipSlaveAPIForward(sc_module_name name): basic_port_forwarder<shipSlaveAPI<T>, shipMasterAPI<T>, GenericTransaction, GenericPhase>(name){}
};

#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

  ship/
    ship_datatypes.h
    ship_masterport.h
    ship_serializable_if.h
    ship_slaveport.h
  basicPorts.h
  basicPorts2.h
  shipAPI.h
  simplebusAPI.h