Jump to content

hierarchical bind


Recommended Posts

hi,

 

all socket  are defined throught there interfaces

 

[basic.h]

#ifndef BASIC_H

#define BASIC_H

#include <systemc>

#include <tlm.h>

#include <stdint.h>

namespace basic {

   typedef uint32_t addr_t;

   typedef uint32_t data_t;

}

 

#include "initiator_socket.h"

#include "target_socket.h"

#endif

 

[/end ]

 

[initiator_socket]

#ifndef BASIC_INITIATOR_SOCKET_H
#define BASIC_INITIATOR_SOCKET_H

#ifndef BASIC_H
#error include "basic.h"
#endif

#include <vector>

namespace basic {

   template <typename MODULE, bool MULTIPORT = false>
   class initiator_socket :
         public tlm::tlm_initiator_socket<CHAR_BIT * sizeof(data_t),
               tlm::tlm_base_protocol_types, MULTIPORT?0:1>,
         private tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types>
   {
      typedef tlm::tlm_initiator_socket<CHAR_BIT * sizeof(data_t),
         tlm::tlm_base_protocol_types, MULTIPORT?0:1> base_type;
      typedef tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types> bw_if_type;

      public:

      initiator_socket() :
            base_type(sc_core::sc_gen_unique_name(kind())),
            time(sc_core::SC_ZERO_TIME)
      {
         init();
      }

      explicit initiator_socket(const char* name) :
            base_type(name),
            time(sc_core::SC_ZERO_TIME)
      {
         init();
      }

      ~initiator_socket() {
         tlm::tlm_generic_payload* trans;
         while(!container.empty()) {
            trans = container.back();
            container.pop_back();
            delete trans;
         }
      }

      tlm::tlm_response_status read(const addr_t& addr, data_t& data, int port = 0) {
         tlm::tlm_generic_payload* trans;
     // allocate the payload
         if(!container.empty()) {
            trans = container.back();
            container.pop_back();
         }
         else {
            trans = new tlm::tlm_generic_payload();
         }

     // build the payload ...
         trans->set_command(tlm::TLM_READ_COMMAND);
         trans->set_address(addr);

         trans->set_data_ptr(reinterpret_cast<unsigned char*>(&data));
     // No block transaction => just one piece of data
         trans->set_data_length(sizeof(data_t));
     // no streaming => streaming_width == data_length
         trans->set_streaming_width(sizeof(data_t));

     // ... and send it.
         (*this)[port]->b_transport(*trans, time);

         container.push_back(trans);

         return trans->get_response_status();
      }

      tlm::tlm_response_status write(const addr_t& addr, data_t data, int port = 0) {
         tlm::tlm_generic_payload* trans;

         if(!container.empty()) {
            trans = container.back();
            container.pop_back();
         }
         else {
            trans = new tlm::tlm_generic_payload();
         }

         trans->set_command(tlm::TLM_WRITE_COMMAND);
         trans->set_address(addr);

         trans->set_data_ptr(reinterpret_cast<unsigned char*>(&data));
         trans->set_data_length(sizeof(data_t));
         trans->set_streaming_width(sizeof(data_t));

         (*this)[port]->b_transport(*trans, time);

         container.push_back(trans);

         return trans->get_response_status();
      }

      virtual const char* kind() const {
         return "basic::initiator_socket";
      }

      void invalidate_direct_mem_ptr(sc_dt::uint64, sc_dt::uint64)
      {
         std::cerr << "invalidate_direct_mem_ptr not implemented" << std::endl;
         abort();
      }

      tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload&,
            tlm::tlm_phase&, sc_core::sc_time&)
      {
         std::cerr << "nb_transport_bw not implemented" << std::endl;
         abort();
      }

      private:

      // container to keep the unused payloads (avoids calling new too often)
      std::vector<tlm::tlm_generic_payload*> container;

      // zero time, but allocated once and for all for performance reasons.
      sc_core::sc_time time;

      
      void init() {
     // we're not actually using the backward interface,
     // but we need to bind the sc_export of the socket to something.
         this->bind(*(static_cast<bw_if_type*>(this)));
      }

   };

}

#endif[/end of initiator_socket]

 

[target-socket]

#ifndef BASIC_TARGET_SOCKET_H
#define BASIC_TARGET_SOCKET_H

#ifndef BASIC_H
#error include "basic.h"
#endif

namespace basic {

   typedef tlm::tlm_target_socket<CHAR_BIT * sizeof(data_t),
         tlm::tlm_base_protocol_types> compatible_socket;

   template <typename MODULE, bool MULTIPORT = false>
   class target_socket :
         public tlm::tlm_target_socket<CHAR_BIT * sizeof(data_t),
            tlm::tlm_base_protocol_types, MULTIPORT?0:1>,
         public tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>
   {
      typedef tlm::tlm_target_socket<CHAR_BIT * sizeof(data_t),
         tlm::tlm_base_protocol_types, MULTIPORT?0:1> base_type;
      typedef tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types> fw_if_type;

      public:

      target_socket() :
            base_type(sc_core::sc_gen_unique_name(kind()))
      {
         init();
      }

      explicit target_socket(const char* name) :
            base_type(name)
      {
         init();
      }

      virtual const char* kind() const {
         return "basic::target_socket";
      }

      bool get_direct_mem_ptr(tlm::tlm_generic_payload&, tlm::tlm_dmi&) {
         std::cerr << "get_direct_mem_ptr not implemented" << std::endl;
         abort();
      }

      unsigned int transport_dbg(tlm::tlm_generic_payload&) {
         std::cerr << "transport_dbg not implemented" << std::endl;
         abort();
      }

      tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload&,
            tlm::tlm_phase&, sc_core::sc_time&) {
         std::cerr << "nb_transport_fw not implemented" << std::endl;
         abort();
      }

      private:

      void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& t) {
         (void) t;
         addr_t addr = static_cast<addr_t>(trans.get_address());
         data_t& data = *(reinterpret_cast<data_t*>(trans.get_data_ptr()));

         switch(trans.get_command()) {
            case tlm::TLM_READ_COMMAND:
               trans.set_response_status(m_mod->read(addr, data));
               break;
            case tlm::TLM_WRITE_COMMAND:
               trans.set_response_status(m_mod->write(addr, data));
               break;
            case tlm::TLM_IGNORE_COMMAND:
               break;
            default:
               trans.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
         }
      }

      void init() {
         // we'll receive transactions ourselves ...
         this->bind(*(static_cast<fw_if_type*>(this)));
     // ... but we'll need to call read/write in the parent module.
         m_mod = dynamic_cast<MODULE*>(this->get_parent_object());
         if(!m_mod) {
            std::cerr << this->name() << ": no parent" << std::endl;
            abort();
         }
      }

      MODULE* m_mod;
   };

}

#endif

[/target_socket]

 

I can't  binding target socket to target socket

I try to add    this->bind(*(static_cast<base_type*>(this)));

but i have this error ""call of ‘(basic::target_socket<Child, false>) (basic::target_socket<TOP, false>&)’ is ambiguous""

 

Please help me

 

 

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...