Jump to content
SystemC

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

 

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×