⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simple_target_socket.h

📁 SystemC Transaction Level Modelling. 是基于SystemC之上的总线互联协议
💻 H
📖 第 1 页 / 共 3 页
字号:
      sc_core::sc_event* m_e;      sc_core::sc_event  m_wakeup;      bool m_suspend;    };        class process_handle_list {    public:      process_handle_list() {}       process_handle_class* get_handle(transaction_type *trans,sc_core::sc_event* e)       {                        typename std::vector<process_handle_class*>::iterator it;        for(it = v.begin(); it != v.end(); it++) {           if ((*it)->m_suspend) {  // found suspended dynamic process, re-use it            (*it)->m_trans = trans; // replace to new one            (*it)->m_e = e;                        return *it;            }        }        return NULL; // no suspended process      }      void put_handle(process_handle_class* ph)      {        v.push_back(ph);      }    private:      std::vector<process_handle_class*> v;    };    process_handle_list m_process_handle;    void nb2b_thread(process_handle_class* h,transaction_type &trans1, sc_core::sc_event *e1)    {       transaction_type *trans = &trans1;      sc_core::sc_event* e = e1;      while(1) {        sc_core::sc_time t = sc_core::SC_ZERO_TIME;        // forward call        assert(m_mod);        (m_mod->*m_b_transport_ptr)(*trans, t);        sc_core::wait(t);        // return path        while (m_response_in_progress) {          sc_core::wait(m_end_response);        }        t = sc_core::SC_ZERO_TIME;        phase_type phase = tlm::BEGIN_RESP;        if (m_owner->bw_nb_transport(*trans, phase, t) != tlm::TLM_COMPLETED) {          m_response_in_progress = true;        }        // cleanup        delete e;        // suspend until next transaction        h->m_suspend = true;        sc_core::wait(h->m_wakeup);        // start next transaction        h->m_suspend = false;        trans = h->m_trans;        e = h->m_e;      }    }    void b2nb_thread()    {      while (true) {        sc_core::wait(m_peq.get_event());        transaction_type* trans;        while ((trans = m_peq.get_next_transaction())!=0) {          assert(m_mod);          assert(m_nb_transport_ptr);          phase_type phase = tlm::BEGIN_REQ;          sc_core::sc_time t = sc_core::SC_ZERO_TIME;          switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) {          case tlm::TLM_COMPLETED:          {            // notify transaction is finished            typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =              m_owner->m_pending_trans.find(trans);            assert(it != m_owner->m_pending_trans.end());            it->second->notify(t);            m_owner->m_pending_trans.erase(it);            break;          }          case tlm::TLM_ACCEPTED:          case tlm::TLM_UPDATED:            switch (phase) {            case tlm::BEGIN_REQ:              m_owner->m_current_transaction = trans;              sc_core::wait(m_owner->m_end_request);              m_owner->m_current_transaction = 0;              break;            case tlm::END_REQ:              sc_core::wait(t);              break;            case tlm::BEGIN_RESP:            {              phase = tlm::END_RESP;              t = sc_core::SC_ZERO_TIME;              (m_mod->*m_nb_transport_ptr)(*trans, phase, t);                        // notify transaction is finished              typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =                m_owner->m_pending_trans.find(trans);              assert(it != m_owner->m_pending_trans.end());              it->second->notify(t);              m_owner->m_pending_trans.erase(it);              break;            }            default:              assert(0); exit(1);            };            break;          default:            assert(0); exit(1);          };        }      }    }    void free(tlm::tlm_generic_payload* trans)    {      mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();      assert(ext);      // notif event first before freeing extensions (reset)      ext->done.notify();      trans->reset();    }  private:    struct mm_end_event_ext : public tlm::tlm_extension<mm_end_event_ext>    {      tlm::tlm_extension_base* clone() const { return NULL; }      void free() {}      void copy_from(tlm::tlm_extension_base const &) {}      sc_core::sc_event done;    };  private:    const std::string m_name;    simple_target_socket *m_owner;    MODULE* m_mod;    NBTransportPtr m_nb_transport_ptr;    BTransportPtr m_b_transport_ptr;    TransportDbgPtr m_transport_dbg_ptr;    GetDirectMemPtr m_get_direct_mem_ptr;    peq_with_get<transaction_type> m_peq;    bool m_response_in_progress;    sc_core::sc_event m_end_response;  };private:  fw_process m_fw_process;  bw_process m_bw_process;  std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;  sc_core::sc_event m_end_request;  transaction_type* m_current_transaction;};//ID Tagged versiontemplate <typename MODULE,          unsigned int BUSWIDTH = 32,          typename TYPES = tlm::tlm_base_protocol_types>class simple_target_socket_tagged :  public tlm::tlm_target_socket<BUSWIDTH, TYPES>{  friend class fw_process;  friend class bw_process;public:  typedef typename TYPES::tlm_payload_type              transaction_type;  typedef typename TYPES::tlm_phase_type                phase_type;  typedef tlm::tlm_sync_enum                            sync_enum_type;  typedef tlm::tlm_fw_transport_if<TYPES>               fw_interface_type;  typedef tlm::tlm_bw_transport_if<TYPES>               bw_interface_type;  typedef tlm::tlm_target_socket<BUSWIDTH, TYPES>       base_type;public:  explicit simple_target_socket_tagged(const char* n = "simple_target_socket_tagged") :    base_type(sc_core::sc_gen_unique_name(n)),    m_fw_process(this),    m_bw_process(this)  {    bind(m_fw_process);  }  // bw transport must come thru us.  tlm::tlm_bw_transport_if<TYPES> * operator ->() {return &m_bw_process;}  // REGISTER_XXX  void register_nb_transport_fw(MODULE* mod,                                sync_enum_type (MODULE::*cb)(int id,                                                             transaction_type&,                                                             phase_type&,                                                             sc_core::sc_time&),                                int id)  {    assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());    m_fw_process.set_nb_transport_ptr(mod, cb);    m_fw_process.set_nb_transport_user_id(id);  }  void register_b_transport(MODULE* mod,                            void (MODULE::*cb)(int id,                                               transaction_type&,                                               sc_core::sc_time&),                            int id)  {    assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());    m_fw_process.set_b_transport_ptr(mod, cb);    m_fw_process.set_b_transport_user_id(id);  }  void register_transport_dbg(MODULE* mod,                              unsigned int (MODULE::*cb)(int id,                                                         transaction_type&),                              int id)  {    assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());    m_fw_process.set_transport_dbg_ptr(mod, cb);    m_fw_process.set_transport_dbg_user_id(id);  }  void register_get_direct_mem_ptr(MODULE* mod,                                   bool (MODULE::*cb)(int id,                                                      transaction_type&,                                                      tlm::tlm_dmi&),                                   int id)  {    assert(!sc_core::sc_get_curr_simcontext()->elaboration_done());    m_fw_process.set_get_direct_mem_ptr(mod, cb);    m_fw_process.set_get_dmi_user_id(id);  }private:  //make call on bw path.  sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)  {    return base_type::operator ->()->nb_transport_bw(trans, phase, t);  }  void bw_invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)  {    base_type::operator ->()->invalidate_direct_mem_ptr(s, e);  }  //Helper class to handle bw path calls  // Needed to detect transaction end when called from b_transport.  class bw_process : public tlm::tlm_bw_transport_if<TYPES>  {  public:    bw_process(simple_target_socket_tagged *p_own) : m_owner(p_own)    {    }    sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)    {      typename std::map<transaction_type*, sc_core::sc_event *>::iterator it;            it = m_owner->m_pending_trans.find(&trans);      if(it == m_owner->m_pending_trans.end()) {        // Not a blocking call, forward.        return m_owner->bw_nb_transport(trans, phase, t);      } else {        if (phase == tlm::END_REQ) {          m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);          return tlm::TLM_ACCEPTED;                } else if (phase == tlm::BEGIN_RESP) {          if (m_owner->m_current_transaction == &trans) {            m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);          }          //TODO: add response-accept delay?          it->second->notify(t);          m_owner->m_pending_trans.erase(it);          return tlm::TLM_COMPLETED;        } else {          assert(0); exit(1);        }//        return tlm::TLM_COMPLETED;  //Should not reach here      }    }    void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)    {      return m_owner->bw_invalidate_direct_mem_ptr(s, e);    }  private:    simple_target_socket_tagged *m_owner;  };  class fw_process : public tlm::tlm_fw_transport_if<TYPES>,                     public tlm::tlm_mm_interface  {  public:    typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,                                                      transaction_type&,                                                     tlm::tlm_phase&,                                                     sc_core::sc_time&);    typedef void (MODULE::*BTransportPtr)(int id,                                           transaction_type&,                                          sc_core::sc_time&);    typedef unsigned int (MODULE::*TransportDbgPtr)(int id,                                                     transaction_type&);    typedef bool (MODULE::*GetDirectMemPtr)(int id,                                             transaction_type&,                                            tlm::tlm_dmi&);          fw_process(simple_target_socket_tagged *p_own) :      m_name(p_own->name()),      m_owner(p_own),      m_mod(0),      m_nb_transport_ptr(0),      m_b_transport_ptr(0),      m_transport_dbg_ptr(0),      m_get_direct_mem_ptr(0),      m_nb_transport_user_id(0),      m_b_transport_user_id(0),      m_transport_dbg_user_id(0),      m_get_dmi_user_id(0),      m_peq(sc_core::sc_gen_unique_name("m_peq")),      m_response_in_progress(false)    {      sc_core::sc_spawn_options opts;      opts.set_sensitivity(&m_peq.get_event());      sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),                         sc_core::sc_gen_unique_name("b2nb_thread"), &opts);    }      void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }    void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }    void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }    void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }    void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)    {      if (m_nb_transport_ptr) {        std::cerr << m_name << ": non-blocking callback allready registered" << std::endl;      } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -