Code Search for Developers
 
 
  

tlm_port.h from GreenSocs at Krugle


Show tlm_port.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

/*******************************************************************************
**
** $Log: tlm_port.h,v $
** Revision 1.2  2006/06/02 15:57:25  klingauf
** A first GenericRouter implementation plus example protocol, scheduler and addressmap
**
** Revision 1.1  2006/05/30 14:56:09  guenzel
** *** empty log message ***
**
**
**
*******************************************************************************/

#ifndef __TLM_PORT_H__
#define __TLM_PORT_H__

#include <systemc.h>
#include "utils/payload_event_queue.h"
#ifdef DUST_ENABLE
#include "utils/gs_dust_port.h"
#endif


namespace tlm {

//forward declaration
  template <class PV, class PVT>
  class tlm_multi_port;

  template <class PV, class PVT>  
  class tlm_port_forwarder_base;
  

  //---------------------------------------------------------------------------
  /**
   * Base for all TLM ports. The communication uses events for both
   * sending and receiving.
   */
  //---------------------------------------------------------------------------
  template <class PV, class PVT>
  class tlm_port
  : public sc_module
  {

  public:

    typedef PV b_if_type;
    typedef PVT if_type;
    typedef payload_event_queue_if<if_type> peq_if_type;
    
#ifdef DUST_ENABLE
    gs_dust_port<b_if_type> b_out;
    sc_export<b_if_type> b_in;

    gs_dust_port<peq_if_type> out;
    sc_export<peq_if_type> in;
#else
    sc_port<b_if_type> b_out;
    sc_export<b_if_type> b_in;

    sc_port<peq_if_type> out;
    sc_export<peq_if_type> in;
#endif

    payload_event_queue<if_type> peq;

    SC_HAS_PROCESS(tlm_port);

    tlm_port( sc_module_name port_name ) :
      sc_module(port_name),
      b_out(sc_gen_unique_name("b_out")),
      b_in(sc_gen_unique_name("b_in")),
      out(sc_gen_unique_name("out")),
      in(sc_gen_unique_name("in"))
    {
      in(peq);
    }

    virtual ~tlm_port() {
    }

    void operator() (tlm_port<b_if_type,if_type>& other) {
      b_out(other.b_in);
      other.b_out(b_in);
      out(other.in);
      other.out(in);
    }

    void bind_b_if(b_if_type& other) {
      b_in(other);
    }

    void operator() (tlm_multi_port<b_if_type,if_type>& other) {
      b_out(other.b_in);
      other.b_bind_out_port(b_in);
      out(other.in);
      other.bind_out_port(in);
    }

    void operator() (tlm_port_forwarder_base<b_if_type,if_type>& port_fw_) {
      port_fw_.forward(*this);
    }

    void wait() {
      sc_core::wait(in->default_event());
    }

    void wait(if_type payload) {
      in->wait(payload);
    }

    if_type get_payload() {
      return in->get_payload();
    }

    const sc_event& default_event() {
      return in->default_event();
    }

//    const bool fired() {
//      return in->fired();
//    }
    
  };



  //---------------------------------------------------------------------------
  /**
   * A TLM multi port.
   */
  //---------------------------------------------------------------------------
  template <class PV, class PVT>
  class tlm_multi_port
  : public sc_module
  {

  public:

    typedef PVT if_type;
    typedef PV b_if_type;
    typedef payload_event_queue_if<if_type> peq_if_type;

#ifdef DUST_ENABLE
    gs_dust_port<peq_if_type, 0> out;
    sc_export<peq_if_type> in;

    gs_dust_port<b_if_type, 0> b_out;
    sc_export<b_if_type> b_in;
#else
    sc_port<peq_if_type, 0> out;
    sc_export<peq_if_type> in;

    sc_port<b_if_type, 0> b_out;
    sc_export<b_if_type> b_in;
#endif

    std::vector< sc_export<b_if_type>* > connected_b_in_ports;

    payload_event_queue<if_type> peq;
    std::vector< sc_export<peq_if_type>* > connected_in_ports;
    
    tlm_multi_port( sc_module_name port_name ) :
      sc_module(port_name),
      out(sc_gen_unique_name("out")),
      in(sc_gen_unique_name("in")),
      b_out(sc_gen_unique_name("b_out")),
      b_in(sc_gen_unique_name("b_in"))
    {
      in(peq);
    }

    virtual ~tlm_multi_port() {
    }

    void operator() (tlm_port<b_if_type,if_type>& other) {
      b_bind_out_port(other.b_in);
      other.b_out(b_in);
      bind_out_port(other.in);
      other.out(in);
    }

    void bind_b_if(b_if_type& other) {
      b_in(other);
    }

    void operator() (tlm_multi_port<b_if_type,if_type>& other) {
      SC_REPORT_FATAL(sc_core::SC_ID_NOT_IMPLEMENTED_, "multi-to-multi-port binding not supported (yet).");
    }

    void operator() (tlm_port_forwarder_base<b_if_type,if_type>& port_fw_) {
      port_fw_.forward(*this);
    }

    void bind_out_port(sc_export<peq_if_type>& in){
      connected_in_ports.push_back(&in);
      out(in);
    }
    
    void b_bind_out_port(sc_export<b_if_type>& b_in){
      connected_b_in_ports.push_back(&b_in);
      b_out(b_in);
    }

    void wait() {
      sc_core::wait(in->default_event());
    }

    void wait(if_type payload) {
      in->wait(payload);
    }

    if_type get_payload() {
      return in->get_payload();
    }

    const sc_event& default_event() {
      return in->default_event();
    }

    const bool fired() {
      return in->fired();
    }

  };


  //---------------------------------------------------------------------------
  /**
   * Base class from which port forwarders can be created
   */
  //---------------------------------------------------------------------------
  template <class PV, class PVT>
  class tlm_port_forwarder_base : public sc_module{
    public:
    
      tlm_port_forwarder_base(sc_module_name name): sc_module(name), singleNmulti(false),bound(false),forwarding(false){}
  
      //bind forward port to tlm_port
      void bind(tlm_port<PV, PVT>& port_){
        if(bound) SC_REPORT_ERROR(name(), "Port is already bound.");
        bound=true;
        if (singleNmulti) (*m_port)(port_);
        else (*m_multi_port)(port_);
      }

      //bind forward port to tlm_multi_port
      void bind( tlm_multi_port<PV, PVT>& port_ )
      { 
        if(bound) SC_REPORT_ERROR(name(), "Port is already bound.");
        bound=true;
        if (singleNmulti) (*m_port)(port_); 
        else (*m_multi_port)(port_);
      }

      //this method binds a forward port to another forward port
      //unfortunately there can be no short notation for this as the () operator is already used to forward a forward port... Dang!
      void bind(tlm_port_forwarder_base<PV, PVT>& port_)
      {
        if(bound) SC_REPORT_ERROR(name(), "Port is already bound.");
        bound=true;
        port_.setBound(); 
        if(singleNmulti){
          if(port_.getSNM())
            (*m_port)(*(port_.getTlmPort()));
          else
            (*m_port)(*(port_.getTlmMultiPort()));
        }
        else{
          if(port_.getSNM())
            (*m_multi_port)(*(port_.getTlmPort()));
          else
            (*m_multi_port)(*(port_.getTlmMultiPort()));
        }
      }
      
      //forward a forward port
      void forward( tlm_port_forwarder_base<PV, PVT>& port_ )
      { 
        //from the point of view of the fw port, it's bound when it is being forwarded to another fw port
        //that's why bound is checked within a forward method
        if(bound) SC_REPORT_ERROR(name(), "Port is already bound a port.");
        bound=true;
        if (singleNmulti) port_.forward(*m_port); 
        else port_.forward(*m_multi_port);
      }
      
      //this method gets called when a forward port is bound to a tlm_port
      //this could either mean to forward this port or to bind it
      //the default implemtation assumes forwarding
      virtual void forward(tlm_port<PV, PVT>& port_)
      {
        if(forwarding) SC_REPORT_ERROR(name(), "Port is already forwarding a port.");
        forwarding=true;
        m_port=&port_;
        singleNmulti=true;
      }

      //this method gets called when a forward port is bound to a tlm_multi_port
      //this could either mean to forward this port or to bind it
      //the default implemtation assumes forwarding
      virtual void forward(tlm_multi_port<PV, PVT>& port_)
      {
        if(forwarding) SC_REPORT_ERROR(name(), "Port is already forwarding a port.");
        forwarding=true;       
        m_multi_port=&port_;
        singleNmulti=false;
      }
      
      virtual void start_of_simulation(){
        if (!bound)
          SC_REPORT_ERROR(name(), "Port is not bound.");
        if (!forwarding)
          SC_REPORT_ERROR(name(), "Port is not forwarding a port.");
      }
      
      //some getters
      bool getSNM(){return singleNmulti;}
      tlm_port<PV, PVT>* getTlmPort(){return m_port;}
      tlm_multi_port<PV, PVT>* getTlmMultiPort(){return m_multi_port;}
      void setBound(){bound=true;}
        
    private:
      tlm_port<PV, PVT>* m_port;
      tlm_multi_port<PV, PVT>* m_multi_port;
      bool singleNmulti;
      bool bound;
      bool forwarding;
  };


} // 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

  attributeBase.h
  attributes.h
  tlm.h
  tlm_b_if.h
  tlm_port.h
  tlm_slave_if.h
  transactionBase.h