summaryrefslogtreecommitdiff
path: root/src/systemc/ext/tlm_utils/simple_target_socket.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/ext/tlm_utils/simple_target_socket.h')
-rw-r--r--src/systemc/ext/tlm_utils/simple_target_socket.h1996
1 files changed, 1036 insertions, 960 deletions
diff --git a/src/systemc/ext/tlm_utils/simple_target_socket.h b/src/systemc/ext/tlm_utils/simple_target_socket.h
index 7e4c3a197..7830e2a8b 100644
--- a/src/systemc/ext/tlm_utils/simple_target_socket.h
+++ b/src/systemc/ext/tlm_utils/simple_target_socket.h
@@ -17,1116 +17,1192 @@
*****************************************************************************/
-// *****************************************************************************
-// Modified by John Aynsley, Doulos, Feb 2009,
-// Fix a bug in simple_target_socket and simple_target_socket_tagged
-// with the addition of one new line of code in each: wait(*e);
-// *****************************************************************************
-
-// *****************************************************************************
-// Modified by John Aynsley on behalf of Robert Guenzel, May 2011,
-// Fix a bug in simple_target_socket and simple_target_socket_tagged
-// with the addition of one new line of code in each: wait(t);
-// *****************************************************************************
-
-
-#ifndef TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_
-#define TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_
-
-#ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
-# define SC_INCLUDE_DYNAMIC_PROCESSES
-#endif
+#ifndef __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__
+#define __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__
#include <systemc>
#include <tlm>
+
#include "tlm_utils/convenience_socket_bases.h"
#include "tlm_utils/peq_with_get.h"
-namespace tlm_utils {
+namespace tlm_utils
+{
-template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
- , sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND >
-class simple_target_socket_b
- : public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
- , protected simple_socket_base
+template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
+ sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
+class simple_target_socket_b :
+ public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>,
+ protected simple_socket_base
{
- 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,1,POL> base_type;
-
-public:
- static const char* default_name()
- { return sc_core::sc_gen_unique_name("simple_target_socket"); }
-
- explicit simple_target_socket_b(const char* n = default_name())
- : base_type(n)
- , m_fw_process(this)
- , m_bw_process(this)
- {
- bind(m_fw_process);
- }
-
- using base_type::bind;
-
- // 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)(transaction_type&,
- phase_type&,
- sc_core::sc_time&))
- {
- elaboration_check("register_nb_transport_fw");
- m_fw_process.set_nb_transport_ptr(mod, cb);
- }
-
- void register_b_transport(MODULE* mod,
- void (MODULE::*cb)(transaction_type&,
- sc_core::sc_time&))
- {
- elaboration_check("register_b_transport");
- m_fw_process.set_b_transport_ptr(mod, cb);
- }
-
- void register_transport_dbg(MODULE* mod,
- unsigned int (MODULE::*cb)(transaction_type&))
- {
- elaboration_check("register_transport_dbg");
- m_fw_process.set_transport_dbg_ptr(mod, cb);
- }
-
- void register_get_direct_mem_ptr(MODULE* mod,
- bool (MODULE::*cb)(transaction_type&,
- tlm::tlm_dmi&))
- {
- elaboration_check("register_get_direct_mem_ptr");
- m_fw_process.set_get_direct_mem_ptr(mod, cb);
- }
-
-protected:
- void start_of_simulation()
- {
- base_type::start_of_simulation();
- m_fw_process.start_of_simulation();
- }
-
-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>
- {
+ friend class fw_process;
+ friend class bw_process;
public:
- bw_process(simple_target_socket_b *p_own) : m_owner(p_own)
- {
- }
+ 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, 1, POL> base_type;
- sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+ public:
+ static const char *
+ default_name()
{
- typename std::map<transaction_type*, sc_core::sc_event *>::iterator 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);
-
- }
-
- if (phase == tlm::END_REQ) {
- m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
- return tlm::TLM_ACCEPTED;
- }
- 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;
- }
- m_owner->display_error("invalid phase received");
- return tlm::TLM_COMPLETED;
+ return sc_core::sc_gen_unique_name("simple_target_socket");
}
- void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+ explicit simple_target_socket_b(const char *n=default_name()) :
+ base_type(n), m_fw_process(this), m_bw_process(this)
{
- return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+ bind(m_fw_process);
}
- private:
- simple_target_socket_b *m_owner;
- };
+ using base_type::bind;
- class fw_process : public tlm::tlm_fw_transport_if<TYPES>,
- public tlm::tlm_mm_interface
- {
- public:
- typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
- phase_type&,
- sc_core::sc_time&);
- typedef void (MODULE::*BTransportPtr)(transaction_type&,
- sc_core::sc_time&);
- typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
- typedef bool (MODULE::*GetDirectMemPtr)(transaction_type&,
- tlm::tlm_dmi&);
-
- fw_process(simple_target_socket_b *p_own) :
- 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_peq(sc_core::sc_gen_unique_name("m_peq")),
- m_response_in_progress(false)
- {}
+ // bw transport must come through us.
+ tlm::tlm_bw_transport_if<TYPES> *operator -> () { return &m_bw_process; }
- void start_of_simulation()
+ // REGISTER_XXX
+ void
+ register_nb_transport_fw(MODULE *mod,
+ sync_enum_type (MODULE::*cb)(
+ transaction_type &, phase_type &, sc_core::sc_time &))
{
- if (!m_b_transport_ptr && m_nb_transport_ptr) { // only spawn b2nb_thread, if needed
- sc_core::sc_spawn_options opts;
- opts.set_sensitivity(&m_peq.get_event());
- opts.dont_initialize();
- sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
- sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
- }
+ elaboration_check("register_nb_transport_fw");
+ m_fw_process.set_nb_transport_ptr(mod, cb);
}
- void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
+ void
+ register_b_transport(MODULE *mod,
+ void (MODULE::*cb)(transaction_type &, sc_core::sc_time &))
{
- if (m_nb_transport_ptr) {
- m_owner->display_warning("non-blocking callback already registered");
- return;
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_nb_transport_ptr = p;
+ elaboration_check("register_b_transport");
+ m_fw_process.set_b_transport_ptr(mod, cb);
}
- void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ void
+ register_transport_dbg(MODULE *mod,
+ unsigned int (MODULE::*cb)(transaction_type &))
{
- if (m_b_transport_ptr) {
- m_owner->display_warning("blocking callback already registered");
- return;
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_b_transport_ptr = p;
+ elaboration_check("register_transport_dbg");
+ m_fw_process.set_transport_dbg_ptr(mod, cb);
}
- void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
+ void
+ register_get_direct_mem_ptr(MODULE *mod,
+ bool (MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
{
- if (m_transport_dbg_ptr) {
- m_owner->display_warning("debug callback already registered");
- return;
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_transport_dbg_ptr = p;
+ elaboration_check("register_get_direct_mem_ptr");
+ m_fw_process.set_get_direct_mem_ptr(mod, cb);
}
- void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
+ protected:
+ void
+ start_of_simulation()
{
- if (m_get_direct_mem_ptr) {
- m_owner->display_warning("get DMI pointer callback already registered");
- return;
- }
- sc_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
- sc_assert(m_mod);
- return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
- }
-
- // nb->b conversion
- if (m_b_transport_ptr) {
- if (phase == tlm::BEGIN_REQ) {
- // prepare thread to do blocking call
- process_handle_class * ph = m_process_handle.get_handle(&trans);
-
- if (!ph) { // create new dynamic process
- ph = new process_handle_class(&trans);
- m_process_handle.put_handle(ph);
-
- sc_core::sc_spawn_options opts;
- opts.dont_initialize();
- opts.set_sensitivity(&ph->m_e);
-
- sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread,this, ph),
- sc_core::sc_gen_unique_name("nb2b_thread"), &opts);
- }
-
- ph->m_e.notify(t);
- return tlm::TLM_ACCEPTED;
- }
- if (phase == tlm::END_RESP) {
- m_response_in_progress = false;
- m_end_response.notify(t);
- return tlm::TLM_COMPLETED;
- }
- m_owner->display_error("invalid phase received");
- return tlm::TLM_COMPLETED;
- }
- m_owner->display_error("no non-blocking transport callback registered");
- return tlm::TLM_COMPLETED;
+ base_type::start_of_simulation();
+ m_fw_process.start_of_simulation();
}
- void b_transport(transaction_type& trans, sc_core::sc_time& t)
+ private:
+ // Make call on bw path.
+ sync_enum_type
+ bw_nb_transport(transaction_type &trans, phase_type &phase,
+ sc_core::sc_time &t)
{
- if (m_b_transport_ptr) {
- // forward call
- sc_assert(m_mod);
- (m_mod->*m_b_transport_ptr)(trans, t);
- return;
- }
-
- // b->nb conversion
- 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);
- }
- return;
- }
-
- // should not be reached
- m_owner->display_error("no blocking transport callback registered");
+ return base_type::operator -> ()->nb_transport_bw(trans, phase, t);
}
- unsigned int transport_dbg(transaction_type& trans)
+ void
+ bw_invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e)
{
- if (m_transport_dbg_ptr) {
- // forward call
- sc_assert(m_mod);
- return (m_mod->*m_transport_dbg_ptr)(trans);
- }
- // No debug support
- return 0;
+ base_type::operator -> ()->invalidate_direct_mem_ptr(s, e);
}
- bool get_direct_mem_ptr(transaction_type& trans,
- tlm::tlm_dmi& dmi_data)
+ // 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>
{
- if (m_get_direct_mem_ptr) {
- // forward call
- sc_assert(m_mod);
- return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
- }
- // 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;
- }
+ public:
+ bw_process(simple_target_socket_b *p_own) : m_owner(p_own) {}
- private:
+ 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 =
+ m_owner->m_pending_trans.find(&trans);
-// dynamic process handler for nb2b conversion
+ if (it == m_owner->m_pending_trans.end()) {
+ // Not a blocking call, forward.
+ return m_owner->bw_nb_transport(trans, phase, t);
+
+ }
+
+ if (phase == tlm::END_REQ) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ return tlm::TLM_ACCEPTED;
+ }
+ if (phase == tlm::BEGIN_RESP) {
+ if (m_owner->m_current_transaction == &trans) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ }
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ return tlm::TLM_COMPLETED;
+ }
+ m_owner->display_error("invalid phase received");
+ return tlm::TLM_COMPLETED;
+ }
- class process_handle_class {
- public:
- explicit process_handle_class(transaction_type * trans)
- : m_trans(trans),m_suspend(false) {}
+ void
+ invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e)
+ {
+ return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+ }
- transaction_type* m_trans;
- sc_core::sc_event m_e;
- bool m_suspend;
+ private:
+ simple_target_socket_b *m_owner;
};
- class process_handle_list {
- public:
- process_handle_list() {}
-
- ~process_handle_list() {
- for( typename std::vector<process_handle_class*>::iterator
- it=v.begin(), end = v.end(); it != end; ++it )
- delete *it;
- }
-
- process_handle_class* get_handle(transaction_type *trans)
- {
- 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_suspend = false;
- return *it;
- }
+ class fw_process : public tlm::tlm_fw_transport_if<TYPES>,
+ public tlm::tlm_mm_interface
+ {
+ public:
+ typedef sync_enum_type (MODULE::*NBTransportPtr)(
+ transaction_type &, phase_type &, sc_core::sc_time &);
+ typedef void (MODULE::*BTransportPtr)(
+ transaction_type &, sc_core::sc_time &);
+ typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type &);
+ typedef bool (MODULE::*GetDirectMemPtr)(
+ transaction_type &, tlm::tlm_dmi &);
+
+ fw_process(simple_target_socket_b *p_own) :
+ 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_peq(sc_core::sc_gen_unique_name("m_peq")),
+ m_response_in_progress(false)
+ {}
+
+ void
+ start_of_simulation()
+ {
+ // Only spawn b2nb_thread, if needed.
+ if (!m_b_transport_ptr && m_nb_transport_ptr) {
+ sc_core::sc_spawn_options opts;
+ opts.set_sensitivity(&m_peq.get_event());
+ opts.dont_initialize();
+ sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
+ sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
+ }
}
- return NULL; // no suspended process
- }
- void put_handle(process_handle_class* ph)
- {
- v.push_back(ph);
- }
+ void
+ set_nb_transport_ptr(MODULE *mod, NBTransportPtr p)
+ {
+ if (m_nb_transport_ptr) {
+ m_owner->display_warning(
+ "non-blocking callback already registered");
+ return;
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_nb_transport_ptr = p;
+ }
- private:
- std::vector<process_handle_class*> v;
- };
+ void
+ set_b_transport_ptr(MODULE *mod, BTransportPtr p)
+ {
+ if (m_b_transport_ptr) {
+ m_owner->display_warning(
+ "blocking callback already registered");
+ return;
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_b_transport_ptr = p;
+ }
- process_handle_list m_process_handle;
+ void
+ set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p)
+ {
+ if (m_transport_dbg_ptr) {
+ m_owner->display_warning("debug callback already registered");
+ return;
+ }
+ sc_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) {
+ m_owner->display_warning(
+ "get DMI pointer callback already registered");
+ return;
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_get_direct_mem_ptr = p;
+ }
- void nb2b_thread(process_handle_class* h)
- {
+ // 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.
+ sc_assert(m_mod);
+ return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
+ }
- while(1) {
- transaction_type *trans = h->m_trans;
- sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+ // nb->b conversion
+ if (m_b_transport_ptr) {
+ if (phase == tlm::BEGIN_REQ) {
+ // Prepare thread to do blocking call.
+ process_handle_class *ph =
+ m_process_handle.get_handle(&trans);
+
+ if (!ph) { // Create new dynamic process.
+ ph = new process_handle_class(&trans);
+ m_process_handle.put_handle(ph);
+
+ sc_core::sc_spawn_options opts;
+ opts.dont_initialize();
+ opts.set_sensitivity(&ph->m_e);
+
+ sc_core::sc_spawn(
+ sc_bind(&fw_process::nb2b_thread, this, ph),
+ sc_core::sc_gen_unique_name("nb2b_thread"),
+ &opts);
+ }
+
+ ph->m_e.notify(t);
+ return tlm::TLM_ACCEPTED;
+ }
+ if (phase == tlm::END_RESP) {
+ m_response_in_progress = false;
+ m_end_response.notify(t);
+ return tlm::TLM_COMPLETED;
+ }
+ m_owner->display_error("invalid phase received");
+ return tlm::TLM_COMPLETED;
+ }
+ m_owner->display_error(
+ "no non-blocking transport callback registered");
+ return tlm::TLM_COMPLETED;
+ }
- // forward call
- sc_assert(m_mod);
- (m_mod->*m_b_transport_ptr)(*trans, t);
+ void
+ b_transport(transaction_type &trans, sc_core::sc_time &t)
+ {
+ if (m_b_transport_ptr) {
+ // Forward call.
+ sc_assert(m_mod);
+ (m_mod->*m_b_transport_ptr)(trans, t);
+ return;
+ }
- sc_core::wait(t);
+ // b->nb conversion
+ 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);
+ }
+ return;
+ }
- // return path
- while (m_response_in_progress) {
- sc_core::wait(m_end_response);
+ // Should not be reached.
+ m_owner->display_error(
+ "no blocking transport callback registered");
}
- t = sc_core::SC_ZERO_TIME;
- phase_type phase = tlm::BEGIN_RESP;
- sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
- if ( !(sync == tlm::TLM_COMPLETED ||
- (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) {
- m_response_in_progress = true;
+
+ unsigned int
+ transport_dbg(transaction_type &trans)
+ {
+ if (m_transport_dbg_ptr) {
+ // Forward call.
+ sc_assert(m_mod);
+ return (m_mod->*m_transport_dbg_ptr)(trans);
+ }
+ // No debug support.
+ return 0;
}
- // suspend until next transaction
- h->m_suspend = true;
- sc_core::wait();
- }
- }
+ bool
+ get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
+ {
+ if (m_get_direct_mem_ptr) {
+ // Forward call.
+ sc_assert(m_mod);
+ return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
+ }
+ // 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;
+ }
- void b2nb_thread()
- {
- while (true) {
- transaction_type* trans;
- while ((trans = m_peq.get_next_transaction())!=0) {
- sc_assert(m_mod);
- sc_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);
- sc_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:
+ private:
+
+ // Dynamic process handler for nb2b conversion.
+
+ class process_handle_class
+ {
+ public:
+ explicit process_handle_class(transaction_type *trans) :
+ m_trans(trans), m_suspend(false)
+ {}
+
+ transaction_type *m_trans;
+ sc_core::sc_event m_e;
+ bool m_suspend;
+ };
+
+ class process_handle_list
+ {
+ public:
+ process_handle_list() {}
+
+ ~process_handle_list()
{
- phase = tlm::END_RESP;
- sc_core::wait(t); // This line is a bug fix added in TLM-2.0.2
- 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);
- sc_assert(it != m_owner->m_pending_trans.end());
- it->second->notify(t);
- m_owner->m_pending_trans.erase(it);
- break;
+ for (typename std::vector<
+ process_handle_class *>::iterator it = v.begin(),
+ end = v.end(); it != end; ++it) {
+ delete *it;
+ }
}
- default:
- m_owner->display_error("invalid phase received");
+ process_handle_class *
+ get_handle(transaction_type *trans)
+ {
+ 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_suspend = false;
+ return *it;
+ }
+ }
+ return NULL; // No suspended process.
}
- break;
- default:
- m_owner->display_error("invalid sync value received");
- }
+ 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)
+ {
+ while (1) {
+ transaction_type *trans = h->m_trans;
+ sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+ // Forward call.
+ sc_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;
+ sync_enum_type sync =
+ m_owner->bw_nb_transport(*trans, phase, t);
+ if (!(sync == tlm::TLM_COMPLETED ||
+ (sync == tlm::TLM_UPDATED &&
+ phase == tlm::END_RESP))) {
+ m_response_in_progress = true;
+ }
+
+ // Suspend until next transaction.
+ h->m_suspend = true;
+ sc_core::wait();
+ }
}
- sc_core::wait();
- }
- }
- void free(tlm::tlm_generic_payload* trans)
- {
- mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
- sc_assert(ext);
- // notif event first before freeing extensions (reset)
- ext->done.notify();
- trans->reset();
- }
+ void
+ b2nb_thread()
+ {
+ while (true) {
+ transaction_type *trans;
+ while ((trans = m_peq.get_next_transaction()) != 0) {
+ sc_assert(m_mod);
+ sc_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);
+ sc_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;
+ // This line is a bug fix added in TLM-2.0.2
+ sc_core::wait(t);
+ 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);
+ sc_assert(it !=
+ m_owner->m_pending_trans.end());
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ break;
+ }
+
+ default:
+ m_owner->display_error("invalid phase received");
+ }
+ break;
+
+ default:
+ m_owner->display_error("invalid sync value received");
+ }
+ }
+ sc_core::wait();
+ }
+ }
- 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;
+ void
+ free(tlm::tlm_generic_payload *trans)
+ {
+ mm_end_event_ext *ext =
+ trans->template get_extension<mm_end_event_ext>();
+ sc_assert(ext);
+ // Notify 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:
+ simple_target_socket_b *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:
- simple_target_socket_b *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:
- const sc_core::sc_object* get_socket() const { return this; }
-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;
+ const sc_core::sc_object *get_socket() const { return this; }
+
+ 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;
};
-template< typename MODULE, unsigned int BUSWIDTH = 32
- , typename TYPES = tlm::tlm_base_protocol_types >
-class simple_target_socket
- : public simple_target_socket_b<MODULE,BUSWIDTH,TYPES>
+template <typename MODULE, unsigned int BUSWIDTH=32,
+ typename TYPES=tlm::tlm_base_protocol_types>
+class simple_target_socket :
+ public simple_target_socket_b<MODULE, BUSWIDTH, TYPES>
{
- typedef simple_target_socket_b<MODULE,BUSWIDTH,TYPES> socket_b;
-public:
- simple_target_socket() : socket_b() {}
- explicit simple_target_socket(const char* name) : socket_b(name) {}
+ typedef simple_target_socket_b<MODULE, BUSWIDTH, TYPES> socket_b;
+ public:
+ simple_target_socket() : socket_b() {}
+ explicit simple_target_socket(const char *name) : socket_b(name) {}
};
-template< typename MODULE, unsigned int BUSWIDTH = 32
- , typename TYPES = tlm::tlm_base_protocol_types >
-class simple_target_socket_optional
- : public simple_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
+template <typename MODULE, unsigned int BUSWIDTH=32,
+ typename TYPES=tlm::tlm_base_protocol_types>
+class simple_target_socket_optional :
+ public simple_target_socket_b<MODULE, BUSWIDTH, TYPES,
+ sc_core::SC_ZERO_OR_MORE_BOUND>
{
- typedef simple_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
-public:
- simple_target_socket_optional() : socket_b() {}
- explicit simple_target_socket_optional(const char* name) : socket_b(name) {}
+ typedef simple_target_socket_b<MODULE, BUSWIDTH, TYPES,
+ sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
+ public:
+ simple_target_socket_optional() : socket_b() {}
+ explicit simple_target_socket_optional(const char *name) :
+ socket_b(name)
+ {}
};
-//ID Tagged version
-template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
- , sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND >
-class simple_target_socket_tagged_b
- : public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
- , protected simple_socket_base
+// ID Tagged version.
+template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
+ sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
+class simple_target_socket_tagged_b :
+ public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>,
+ protected simple_socket_base
{
- 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,1,POL> base_type;
-
-public:
- static const char* default_name()
- { return sc_core::sc_gen_unique_name("simple_target_socket_tagged"); }
-
- explicit simple_target_socket_tagged_b(const char* n = default_name())
- : base_type(n)
- , m_fw_process(this)
- , m_bw_process(this)
- {
- bind(m_fw_process);
- }
-
- using base_type::bind;
-
- // 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)
- {
- elaboration_check("register_nb_transport_fw");
- 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)
- {
- elaboration_check("register_b_transport");
- 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)
- {
- elaboration_check("register_transport_dbg");
- 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)
- {
- elaboration_check("register_get_direct_mem_ptr");
- m_fw_process.set_get_direct_mem_ptr(mod, cb);
- m_fw_process.set_get_dmi_user_id(id);
- }
-
-protected:
- void start_of_simulation()
- {
- base_type::start_of_simulation();
- m_fw_process.start_of_simulation();
- }
-
-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>
- {
+ friend class fw_process;
+ friend class bw_process;
public:
- bw_process(simple_target_socket_tagged_b *p_own) : m_owner(p_own)
- {
- }
+ 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, 1, POL> base_type;
- sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase, sc_core::sc_time &t)
+ public:
+ static const char *
+ default_name()
{
- typename std::map<transaction_type*, sc_core::sc_event *>::iterator 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);
- }
- if (phase == tlm::END_REQ) {
- m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
- return tlm::TLM_ACCEPTED;
- }
- 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;
- }
- m_owner->display_error("invalid phase received");
- return tlm::TLM_COMPLETED;
+ return sc_core::sc_gen_unique_name("simple_target_socket_tagged");
}
- void invalidate_direct_mem_ptr(sc_dt::uint64 s,sc_dt::uint64 e)
+ explicit simple_target_socket_tagged_b(const char *n=default_name()) :
+ base_type(n), m_fw_process(this), m_bw_process(this)
{
- return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+ bind(m_fw_process);
}
- private:
- simple_target_socket_tagged_b *m_owner;
- };
+ using base_type::bind;
- 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&,
- phase_type&,
- 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_b *p_own) :
- 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)
- {}
+ // bw transport must come through us.
+ tlm::tlm_bw_transport_if<TYPES> *operator -> () { return &m_bw_process; }
- void start_of_simulation()
+ // 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)
{
- if (!m_b_transport_ptr && m_nb_transport_ptr) { // only spawn b2nb_thread, if needed
- sc_core::sc_spawn_options opts;
- opts.set_sensitivity(&m_peq.get_event());
- opts.dont_initialize();
- sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
- sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
- }
+ elaboration_check("register_nb_transport_fw");
+ m_fw_process.set_nb_transport_ptr(mod, cb);
+ m_fw_process.set_nb_transport_user_id(id);
}
- 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)
+ void
+ register_b_transport(MODULE *mod,
+ void (MODULE::*cb)(int id, transaction_type &,
+ sc_core::sc_time &),
+ int id)
{
- if (m_nb_transport_ptr) {
- m_owner->display_warning("non-blocking callback already registered");
- return;
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_nb_transport_ptr = p;
+ elaboration_check("register_b_transport");
+ m_fw_process.set_b_transport_ptr(mod, cb);
+ m_fw_process.set_b_transport_user_id(id);
}
- void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ void
+ register_transport_dbg(MODULE *mod,
+ unsigned int (MODULE::*cb)(int id, transaction_type &), int id)
{
- if (m_b_transport_ptr) {
- m_owner->display_warning("blocking callback already registered");
- return;
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_b_transport_ptr = p;
+ elaboration_check("register_transport_dbg");
+ m_fw_process.set_transport_dbg_ptr(mod, cb);
+ m_fw_process.set_transport_dbg_user_id(id);
}
- void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
+ void
+ register_get_direct_mem_ptr(MODULE *mod,
+ bool (MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &),
+ int id)
{
- if (m_transport_dbg_ptr) {
- m_owner->display_warning("debug callback already registered");
- return;
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_transport_dbg_ptr = p;
+ elaboration_check("register_get_direct_mem_ptr");
+ m_fw_process.set_get_direct_mem_ptr(mod, cb);
+ m_fw_process.set_get_dmi_user_id(id);
}
- void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
+ protected:
+ void
+ start_of_simulation()
{
- if (m_get_direct_mem_ptr) {
- m_owner->display_warning("get DMI pointer callback already registered");
- }
- sc_assert(!m_mod || m_mod == mod);
- m_mod = mod;
- m_get_direct_mem_ptr = p;
+ base_type::start_of_simulation();
+ m_fw_process.start_of_simulation();
}
-// Interface implementation
- sync_enum_type nb_transport_fw(transaction_type& trans,
- phase_type& phase,
- sc_core::sc_time& t)
+
+ private:
+ // Make call on bw path.
+ sync_enum_type
+ bw_nb_transport(transaction_type &trans, phase_type &phase,
+ sc_core::sc_time &t)
{
- if (m_nb_transport_ptr) {
- // forward call
- sc_assert(m_mod);
- return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
- }
+ return base_type::operator -> ()->nb_transport_bw(trans, phase, t);
+ }
- // nb->b conversion
- if (m_b_transport_ptr) {
- if (phase == tlm::BEGIN_REQ) {
+ void
+ bw_invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e)
+ {
+ base_type::operator -> ()->invalidate_direct_mem_ptr(s, e);
+ }
- // prepare thread to do blocking call
- process_handle_class * ph = m_process_handle.get_handle(&trans);
+ // 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_b *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 =
+ 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);
+ }
+ if (phase == tlm::END_REQ) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ return tlm::TLM_ACCEPTED;
+ }
+ if (phase == tlm::BEGIN_RESP) {
+ if (m_owner->m_current_transaction == &trans) {
+ m_owner->m_end_request.notify(sc_core::SC_ZERO_TIME);
+ }
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ return tlm::TLM_COMPLETED;
+ }
+ m_owner->display_error("invalid phase received");
+ return tlm::TLM_COMPLETED;
+ }
- if (!ph) { // create new dynamic process
- ph = new process_handle_class(&trans);
- m_process_handle.put_handle(ph);
+ void
+ invalidate_direct_mem_ptr(sc_dt::uint64 s, sc_dt::uint64 e)
+ {
+ return m_owner->bw_invalidate_direct_mem_ptr(s, e);
+ }
- sc_core::sc_spawn_options opts;
- opts.dont_initialize();
- opts.set_sensitivity(&ph->m_e);
+ private:
+ simple_target_socket_tagged_b *m_owner;
+ };
- sc_core::sc_spawn(sc_bind(&fw_process::nb2b_thread, this, ph),
- sc_core::sc_gen_unique_name("nb2b_thread"), &opts);
- }
+ 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 &, phase_type &,
+ 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_b *p_own) :
+ 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)
+ {}
+
+ void
+ start_of_simulation()
+ {
+ if (!m_b_transport_ptr && m_nb_transport_ptr) {
+ // Only spawn b2nb_thread if needed.
+ sc_core::sc_spawn_options opts;
+ opts.set_sensitivity(&m_peq.get_event());
+ opts.dont_initialize();
+ sc_core::sc_spawn(sc_bind(&fw_process::b2nb_thread, this),
+ sc_core::sc_gen_unique_name("b2nb_thread"), &opts);
+ }
+ }
- ph->m_e.notify(t);
- return tlm::TLM_ACCEPTED;
+ 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;
}
- if (phase == tlm::END_RESP) {
- m_response_in_progress = false;
- m_end_response.notify(t);
- return tlm::TLM_COMPLETED;
+ 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) {
+ m_owner->display_warning(
+ "non-blocking callback already registered");
+ return;
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_nb_transport_ptr = p;
}
- m_owner->display_error("invalid phase");
- return tlm::TLM_COMPLETED;
- }
- m_owner->display_error("no non-blocking transport callback registered");
- return tlm::TLM_COMPLETED;
- }
+ void
+ set_b_transport_ptr(MODULE* mod, BTransportPtr p)
+ {
+ if (m_b_transport_ptr) {
+ m_owner->display_warning(
+ "blocking callback already registered");
+ return;
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_b_transport_ptr = p;
+ }
- void b_transport(transaction_type& trans, sc_core::sc_time& t)
- {
- if (m_b_transport_ptr) {
- // forward call
- sc_assert(m_mod);
- (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
- return;
- }
-
- // b->nb conversion
- 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();
+ void
+ set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p)
+ {
+ if (m_transport_dbg_ptr) {
+ m_owner->display_warning(
+ "debug callback already registered");
+ return;
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_transport_dbg_ptr = p;
}
- // 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);
+ void
+ set_get_direct_mem_ptr(MODULE *mod, GetDirectMemPtr p)
+ {
+ if (m_get_direct_mem_ptr) {
+ m_owner->display_warning(
+ "get DMI pointer callback already registered");
+ }
+ sc_assert(!m_mod || m_mod == mod);
+ m_mod = mod;
+ m_get_direct_mem_ptr = p;
}
- return;
- }
- m_owner->display_error("no transport callback registered");
- }
+ // 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.
+ sc_assert(m_mod);
+ return (m_mod->*m_nb_transport_ptr)(
+ m_nb_transport_user_id, trans, phase, t);
+ }
- unsigned int transport_dbg(transaction_type& trans)
- {
- if (m_transport_dbg_ptr) {
- // forward call
- sc_assert(m_mod);
- return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
- }
- // No debug support
- return 0;
- }
+ // nb->b conversion
+ if (m_b_transport_ptr) {
+ if (phase == tlm::BEGIN_REQ) {
+
+ // Prepare thread to do blocking call.
+ process_handle_class *ph =
+ m_process_handle.get_handle(&trans);
+
+ if (!ph) { // Create new dynamic process.
+ ph = new process_handle_class(&trans);
+ m_process_handle.put_handle(ph);
+
+ sc_core::sc_spawn_options opts;
+ opts.dont_initialize();
+ opts.set_sensitivity(&ph->m_e);
+
+ sc_core::sc_spawn(
+ sc_bind(&fw_process::nb2b_thread, this, ph),
+ sc_core::sc_gen_unique_name("nb2b_thread"),
+ &opts);
+ }
+
+ ph->m_e.notify(t);
+ return tlm::TLM_ACCEPTED;
+ }
+ if (phase == tlm::END_RESP) {
+ m_response_in_progress = false;
+ m_end_response.notify(t);
+ return tlm::TLM_COMPLETED;
+ }
+ m_owner->display_error("invalid phase");
+ return tlm::TLM_COMPLETED;
+ }
- bool get_direct_mem_ptr(transaction_type& trans,
- tlm::tlm_dmi& dmi_data)
- {
- if (m_get_direct_mem_ptr) {
- // forward call
- sc_assert(m_mod);
- return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
- }
- // 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;
- }
+ m_owner->display_error(
+ "no non-blocking transport callback registered");
+ return tlm::TLM_COMPLETED;
+ }
- private:
-// dynamic process handler for nb2b conversion
+ void
+ b_transport(transaction_type &trans, sc_core::sc_time &t)
+ {
+ if (m_b_transport_ptr) {
+ // Forward call.
+ sc_assert(m_mod);
+ (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
+ return;
+ }
- class process_handle_class {
- public:
- explicit process_handle_class(transaction_type * trans)
- : m_trans(trans),m_suspend(false){}
+ // b->nb conversion
+ 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);
+ }
+ return;
+ }
- transaction_type* m_trans;
- sc_core::sc_event m_e;
- bool m_suspend;
- };
+ m_owner->display_error("no transport callback registered");
+ }
- class process_handle_list {
- public:
- process_handle_list() {}
-
- ~process_handle_list() {
- for( typename std::vector<process_handle_class*>::iterator
- it=v.begin(), end = v.end(); it != end; ++it )
- delete *it;
- }
-
- process_handle_class* get_handle(transaction_type *trans)
- {
- 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_suspend = false;
- return *it;
- }
+ unsigned int
+ transport_dbg(transaction_type &trans)
+ {
+ if (m_transport_dbg_ptr) {
+ // Forward call.
+ sc_assert(m_mod);
+ return (m_mod->*m_transport_dbg_ptr)(
+ m_transport_dbg_user_id, trans);
+ }
+ // No debug support.
+ return 0;
}
- return NULL; // no suspended process
- }
- void put_handle(process_handle_class* ph)
- {
- v.push_back(ph);
- }
+ bool
+ get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
+ {
+ if (m_get_direct_mem_ptr) {
+ // Forward call.
+ sc_assert(m_mod);
+ return (m_mod->*m_get_direct_mem_ptr)(
+ m_get_dmi_user_id, trans, dmi_data);
+ }
+ // 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:
- std::vector<process_handle_class*> v;
- };
+ private:
- process_handle_list m_process_handle;
+ // Dynamic process handler for nb2b conversion.
+ class process_handle_class
+ {
+ public:
+ explicit process_handle_class(transaction_type *trans) :
+ m_trans(trans), m_suspend(false)
+ {}
- void nb2b_thread(process_handle_class* h)
- {
+ transaction_type *m_trans;
+ sc_core::sc_event m_e;
+ bool m_suspend;
+ };
- while(1) {
- transaction_type * trans = h->m_trans;
- sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+ class process_handle_list
+ {
+ public:
+ process_handle_list() {}
- // forward call
- sc_assert(m_mod);
- (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, *trans, t);
+ ~process_handle_list()
+ {
+ for (typename std::vector<
+ process_handle_class *>::iterator it = v.begin(),
+ end = v.end(); it != end; ++it) {
+ delete *it;
+ }
+ }
- sc_core::wait(t);
+ process_handle_class *
+ get_handle(transaction_type *trans)
+ {
+ 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_suspend = false;
+ return *it;
+ }
+ }
+ return NULL; // No suspended process.
+ }
- // 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;
- sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
- if ( !(sync == tlm::TLM_COMPLETED ||
- (sync == tlm::TLM_UPDATED && phase == tlm::END_RESP)) ) {
- m_response_in_progress = true;
+ 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)
+ {
+
+ while (1) {
+ transaction_type *trans = h->m_trans;
+ sc_core::sc_time t = sc_core::SC_ZERO_TIME;
+
+ // Forward call.
+ sc_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;
+ sync_enum_type sync =
+ m_owner->bw_nb_transport(*trans, phase, t);
+ if (!(sync == tlm::TLM_COMPLETED ||
+ (sync == tlm::TLM_UPDATED &&
+ phase == tlm::END_RESP))) {
+ m_response_in_progress = true;
+ }
+
+ // Suspend until next transaction.
+ h->m_suspend = true;
+ sc_core::wait();
+ }
}
- // suspend until next transaction
- h->m_suspend = true;
- sc_core::wait();
- }
- }
-
- void b2nb_thread()
- {
- while (true) {
- transaction_type* trans;
- while ((trans = m_peq.get_next_transaction())!=0) {
- sc_assert(m_mod);
- sc_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);
- sc_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;
- sc_core::wait(t); // This line is a bug fix added in TLM-2.0.2
- 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);
- sc_assert(it != m_owner->m_pending_trans.end());
- it->second->notify(t);
- m_owner->m_pending_trans.erase(it);
- break;
+ void
+ b2nb_thread()
+ {
+ while (true) {
+ transaction_type *trans;
+ while ((trans = m_peq.get_next_transaction()) != 0) {
+ sc_assert(m_mod);
+ sc_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);
+ sc_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;
+ // This line is a bug fix added in TLM-2.0.2.
+ sc_core::wait(t);
+ 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);
+ sc_assert(it !=
+ m_owner->m_pending_trans.end());
+ it->second->notify(t);
+ m_owner->m_pending_trans.erase(it);
+ break;
+ }
+
+ default:
+ m_owner->display_error("invalid phase received");
+ };
+ break;
+
+ default:
+ m_owner->display_error("invalid sync value received");
+ }
+ }
+ sc_core::wait();
}
+ }
- default:
- m_owner->display_error("invalid phase received");
- };
- break;
-
- default:
- m_owner->display_error("invalid sync value received");
- }
+ void
+ free(tlm::tlm_generic_payload *trans)
+ {
+ mm_end_event_ext *ext =
+ trans->template get_extension<mm_end_event_ext>();
+ sc_assert(ext);
+ // Notify event first before freeing extensions (reset).
+ ext->done.notify();
+ trans->reset();
}
- sc_core::wait();
- }
- }
- void free(tlm::tlm_generic_payload* trans)
- {
- mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
- sc_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:
+ simple_target_socket_tagged_b *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:
- 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;
- };
+ const sc_core::sc_object *get_socket() const { return this; }
private:
- simple_target_socket_tagged_b *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:
- const sc_core::sc_object* get_socket() const { return this; }
-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;
+ 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;
};
-template< typename MODULE, unsigned int BUSWIDTH = 32
- , typename TYPES = tlm::tlm_base_protocol_types >
-class simple_target_socket_tagged
- : public simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES>
+template <typename MODULE, unsigned int BUSWIDTH=32,
+ typename TYPES=tlm::tlm_base_protocol_types>
+class simple_target_socket_tagged :
+ public simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
{
- typedef simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES> socket_b;
-public:
- simple_target_socket_tagged() : socket_b() {}
- explicit simple_target_socket_tagged(const char* name) : socket_b(name) {}
+ typedef simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES> socket_b;
+ public:
+ simple_target_socket_tagged() : socket_b() {}
+ explicit simple_target_socket_tagged(const char *name) : socket_b(name) {}
};
-template< typename MODULE, unsigned int BUSWIDTH = 32
- , typename TYPES = tlm::tlm_base_protocol_types >
-class simple_target_socket_tagged_optional
- : public simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
+template <typename MODULE, unsigned int BUSWIDTH=32,
+ typename TYPES=tlm::tlm_base_protocol_types>
+class simple_target_socket_tagged_optional :
+ public simple_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES,
+ sc_core::SC_ZERO_OR_MORE_BOUND>
{
- typedef simple_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
-public:
- simple_target_socket_tagged_optional() : socket_b() {}
- explicit simple_target_socket_tagged_optional(const char* name) : socket_b(name) {}
+ typedef simple_target_socket_tagged_b<
+ MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
+ public:
+ simple_target_socket_tagged_optional() : socket_b() {}
+ explicit simple_target_socket_tagged_optional(const char *name) :
+ socket_b(name)
+ {}
};
} // namespace tlm_utils
-#endif // TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_
+
+#endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_TARGET_SOCKET_H__ */