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

📄 simple_target_socket.h

📁 SystemC Transaction Level Modelling. 是基于SystemC之上的总线互联协议
💻 H
📖 第 1 页 / 共 3 页
字号:
        assert(!m_mod || m_mod == mod);        m_mod = mod;        m_nb_transport_ptr = p;      }    }    void set_b_transport_ptr(MODULE* mod, BTransportPtr p)    {      if (m_b_transport_ptr) {        std::cerr << m_name << ": non-blocking callback allready registered" << std::endl;      } else {        assert(!m_mod || m_mod == mod);        m_mod = mod;        m_b_transport_ptr = p;      }    }    void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)    {      if (m_transport_dbg_ptr) {        std::cerr << m_name << ": debug callback allready registered" << std::endl;      } else {        assert(!m_mod || m_mod == mod);        m_mod = mod;        m_transport_dbg_ptr = p;      }    }    void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)    {      if (m_get_direct_mem_ptr) {        std::cerr << m_name << ": get DMI pointer callback allready registered" << std::endl;      } else {        assert(!m_mod || m_mod == mod);        m_mod = mod;        m_get_direct_mem_ptr = p;      }    }// Interface implementation    sync_enum_type nb_transport_fw(transaction_type& trans,                                   phase_type& phase,                                   sc_core::sc_time& t)    {      if (m_nb_transport_ptr) {        // forward call        assert(m_mod);        return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);      } else if (m_b_transport_ptr) {        if (phase == tlm::BEGIN_REQ) {          // create thread to do blocking call          sc_core::sc_spawn_options opts;          opts.dont_initialize();          sc_core::sc_event *e = new sc_core::sc_event;          opts.set_sensitivity(e);          // sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread, this, sc_ref(trans), e),           //                  sc_core::sc_gen_unique_name("nb2b_thread"), &opts);          process_handle_class * ph = m_process_handle.get_handle(&trans,e);          if (!ph) { // create new dynamic process            ph = new process_handle_class(&trans,e);            m_process_handle.put_handle(ph);            sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread, this, ph, sc_ref(trans), e),                             sc_core::sc_gen_unique_name("nb2b_thread"), &opts);          } else { // reuse existing dynamic process and resume it            ph->m_wakeup.notify(); // immidiate notification          }          e->notify(t);          return tlm::TLM_ACCEPTED;        } else if (phase == tlm::END_RESP) {          m_response_in_progress = false;          m_end_response.notify(t);          return tlm::TLM_COMPLETED;        } else {          assert(0); exit(1);//          return tlm::TLM_COMPLETED;   ///< unreachable code        }      } else {        std::cerr << m_name << ": no transport callback registered" << std::endl;        assert(0); exit(1);//        return tlm::TLM_COMPLETED;   ///< unreachable code      }    }    void b_transport(transaction_type& trans, sc_core::sc_time& t)    {      if (m_b_transport_ptr) {        // forward call        assert(m_mod);        (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);        return;            } else if (m_nb_transport_ptr) {        m_peq.notify(trans, t);        t = sc_core::SC_ZERO_TIME;        mm_end_event_ext mm_ext;        const bool mm_added = !trans.has_mm();        if (mm_added){          trans.set_mm(this);          trans.set_auto_extension(&mm_ext);          trans.acquire();        }        // wait until transaction is finished        sc_core::sc_event end_event;        m_owner->m_pending_trans[&trans] = &end_event;        sc_core::wait(end_event);        if (mm_added) {          // release will not delete the transaction, it will notify mm_ext.done          trans.release();          if (trans.get_ref_count()) {            sc_core::wait(mm_ext.done);          }          trans.set_mm(0);        }      } else {        std::cerr << m_name << ": no transport callback registered" << std::endl;        assert(0); exit(1);//        return tlm::TLM_COMPLETED;   ///< unreachable code      }    }    unsigned int transport_dbg(transaction_type& trans)    {      if (m_transport_dbg_ptr) {        // forward call        assert(m_mod);        return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);      } else {        // No debug support        return 0;      }    }    bool get_direct_mem_ptr(transaction_type& trans,                            tlm::tlm_dmi&  dmi_data)    {      if (m_get_direct_mem_ptr) {        // forward call        assert(m_mod);        return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);      } else {        // No DMI support        dmi_data.allow_read_write();        dmi_data.set_start_address(0x0);        dmi_data.set_end_address((sc_dt::uint64)-1);        return false;      }    }  private:// dynamic process handler for nb2b conversion    class process_handle_class {    public:      process_handle_class(transaction_type * trans,                           sc_core::sc_event* e):        m_trans(trans),m_e(e),m_suspend(false){}      transaction_type*  m_trans;      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)(m_b_transport_user_id, *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)(m_nb_transport_user_id, *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)(m_nb_transport_user_id, *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_tagged *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;    int m_nb_transport_user_id;    int m_b_transport_user_id;    int m_transport_dbg_user_id;    int m_get_dmi_user_id;    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;};}#endif

⌨️ 快捷键说明

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