77    bool m_infinite = 
false;
 
   78    std::vector<T> m_queue;
 
   81    std::unique_ptr<tlm::tlm_generic_payload> m_txn;
 
   84        enum { DELTA_CHANGE, ABSOLUTE_VALUE, INFINITE } cmd;
 
   90        std::lock_guard<std::mutex> 
guard(m_mutex);
 
   91        tlm::tlm_generic_payload 
txn;
 
   93        uint64_t sending = (m_infinite || (m_can_send > m_queue.size())) ? m_queue.size() : m_can_send;
 
   96                txn.deep_copy_from(*m_txn);
 
  100            txn.set_data_ptr(&(m_queue[0]));
 
  101            sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
 
  102            output_socket->b_transport(
txn, delay);
 
  103            m_queue.erase(m_queue.begin(), m_queue.begin() + 
sending);
 
  107    void initiator_ctrl(tlm::tlm_generic_payload& 
txn, sc_core::sc_time& 
t)
 
  109        std::lock_guard<std::mutex> 
guard(m_mutex);
 
  111        ctrl* 
c = (ctrl*)(
txn.get_data_ptr());
 
  113        case ctrl::ABSOLUTE_VALUE:
 
  114            m_can_send = 
c->can_send;
 
  116            SCP_TRACE(())(
"Can send {}", m_can_send);
 
  121                m_send_event.async_attach_suspending();
 
  123                m_send_event.async_detach_suspending();
 
  125        case ctrl::DELTA_CHANGE:
 
  127            m_can_send += 
c->can_send;
 
  129            SCP_TRACE(())(
"Can send {}", m_can_send);
 
  138        m_send_event.notify(sc_core::SC_ZERO_TIME);
 
  140    void send_ctrl(ctrl& 
c)
 
  142        tlm::tlm_generic_payload 
txn;
 
  143        txn.set_data_length(
sizeof(ctrl));
 
  145        txn.set_command(tlm::TLM_IGNORE_COMMAND);
 
  147        input_control_socket->b_transport(
txn, 
t);
 
  150    bool m_bound = 
false;
 
  155        if (m_bound) 
SCP_ERR(())(
"Socket already bound, may only be bound once");
 
  159        if (m_bound) 
SCP_ERR(())(
"Socket already bound, may only be bound once");
 
  163    const char* name() { 
return sc_module::name(); }
 
  165    tlm_utils::simple_target_socket<MODULE, DEFAULT_TLM_BUSWIDTH> input_socket;
 
  166    tlm_utils::simple_initiator_socket<biflow_socket, DEFAULT_TLM_BUSWIDTH> input_control_socket;
 
  168    tlm_utils::simple_initiator_socket<biflow_socket, DEFAULT_TLM_BUSWIDTH> output_socket;
 
  169    tlm_utils::simple_target_socket<biflow_socket, DEFAULT_TLM_BUSWIDTH> output_control_socket;
 
  178        : sc_core::sc_module(name)
 
  179        , input_socket((std::
string(name) + 
"_input_socket").
c_str())
 
  180        , output_socket((std::
string(name) + 
"_output_socket").
c_str())
 
  181        , input_control_socket((std::
string(name) + 
"_input_socket_control").
c_str())
 
  182        , output_control_socket((std::
string(name) + 
"_output_socket_control").
c_str())
 
  190        output_control_socket.register_b_transport(
this, &biflow_socket::initiator_ctrl);
 
  191        m_send_event.async_detach_suspending();
 
 
  194    tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_input_socket() { 
return input_socket; }
 
  195    tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_output_socket() { 
return output_socket; };
 
  196    tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_input_control_socket() { 
return input_control_socket; };
 
  197    tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_output_control_socket() { 
return output_control_socket; };
 
  208        other.new_bind(*
this);
 
  209        output_socket.bind(
other.get_input_socket());
 
  210        input_control_socket.bind(
other.get_output_control_socket());
 
  211        other.get_output_socket().bind(input_socket);
 
  212        other.get_input_control_socket().bind(output_control_socket);
 
 
  229        input_socket.register_b_transport(mod, 
cb);
 
 
  240        c.cmd = ctrl::DELTA_CHANGE;
 
 
  256        c.cmd = ctrl::ABSOLUTE_VALUE;
 
 
  267        c.cmd = ctrl::INFINITE;
 
 
  280        std::lock_guard<std::mutex> 
guard(m_mutex);
 
  281        m_queue.push_back(data);
 
  282        m_send_event.notify();
 
 
  292        if (!m_txn) m_txn = std::make_unique<tlm::tlm_generic_payload>();
 
  293        m_txn->deep_copy_from(
txn);
 
 
  303        sc_core::sc_time delay;
 
  304        output_socket->b_transport(
txn, delay);
 
 
  314        std::lock_guard<std::mutex> 
guard(m_mutex);
 
 
 
  332    class remote : 
public sc_core::sc_object
 
  334        sc_core::sc_vector<remote>& m_remotes;
 
  339        remote* m_sendto = 
nullptr;
 
  341        void route_data(tlm::tlm_generic_payload& 
txn, sc_core::sc_time& 
t)
 
  345            for (
auto& remote : m_remotes) {
 
  346                if (&remote != 
this && (!m_sendto || m_sendto == &remote)) {
 
  348                    remote.socket.set_default_txn(
txn);
 
  349                    for (
int i = 0; 
i < 
txn.get_data_length(); 
i++) {
 
  352                        remote.socket.enqueue(data);
 
  357                SCP_WARN(())(
"Should have been sent - sendto {}", m_sendto->name());
 
  361        remote(sc_core::sc_module_name name, sc_core::sc_vector<struct remote>& r): socket(name), m_remotes(r)
 
  363            socket.register_b_transport(
this, &remote::route_data);
 
  366        void set_sendto(remote* s) { m_sendto = s; }
 
  369    sc_core::sc_vector<remote> m_remotes;
 
  373    cci::cci_param<std::string> p_sendto;
 
  374    remote* m_sendto = 
nullptr;
 
  378        if (!p_sendto.get_value().empty()) {
 
  380                SCP_WARN(())(
"{} sendto {}", remote.name(), m_sendto->name());
 
  381                remote.set_sendto(m_sendto);
 
  382            } 
else if (std::string(
other.name()).find(p_sendto) == 0) {
 
  384                SCP_WARN(())(
"found sendto {}", m_sendto->name());
 
  385                for (
auto& r : m_remotes) {
 
  387                        SCP_WARN(())(
"{} sendto {}", r.name(), m_sendto->name());
 
  388                        r.set_sendto(m_sendto);
 
  392                SCP_WARN(())(
"{} is not sendto {}", 
other.name(), p_sendto.get_value());
 
  400        m_remotes.emplace_back(m_remotes);
 
  401        auto& remote = m_remotes[m_remotes.size() - 1];
 
  402        binding = &(remote.socket);
 
  403        binding->new_bind(
other);
 
  404        sendto_setup(
other, remote);
 
  409        binding->bind_done();
 
  410        binding->can_receive_any();
 
  416        SCP_TRACE(())(
"Biflow Router {} binding to {}", name(), 
other.name());
 
  417        m_remotes.emplace_back(m_remotes);
 
  419        auto& remote = m_remotes[m_remotes.size() - 1];
 
  420        binding = &(remote.socket);
 
  422        binding->bind(
other); 
 
  423        binding->can_receive_any();
 
  426        sendto_setup(
other, remote);
 
  429    tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_input_socket()
 
  432        return binding->get_input_socket();
 
  434    tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_output_socket()
 
  437        return binding->get_output_socket();
 
  439    tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_input_control_socket()
 
  442        return binding->get_input_control_socket();
 
  444    tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_output_control_socket()
 
  447        return binding->get_output_control_socket();
 
  456        enum { DELTA_CHANGE, ABSOLUTE_VALUE, INFINITE } cmd;
 
 
  460        : sc_core::sc_module(name)
 
  461        , m_remotes(
"remote_sockets")
 
  462        , p_sendto(
"sendto", 
sendto, 
"Router all sent data to this port")
 
  467    const char* name() { 
return sc_module::name(); }
 
 
  478    tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_input_socket() { 
return router.get_input_socket(); }
 
  479    tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_output_socket() { 
return router.get_output_socket(); }
 
  480    tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_input_control_socket()
 
  482        return router.get_input_control_socket();
 
  484    tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_output_control_socket()
 
  486        return router.get_output_control_socket();
 
  489    void bind_done() { 
router.bind_done(); }
 
  492    void register_b_transport(
MODULE* mod, 
void (
MODULE::*
cb)(tlm::tlm_generic_payload&, sc_core::sc_time&))
 
  494        main_socket.register_b_transport(mod, 
cb);
 
  496    void can_receive_more(
int i) { main_socket.can_receive_more(
i); }
 
  497    void can_receive_set(
int i) { main_socket.can_receive_set(
i); }
 
  498    void can_receive_any() { main_socket.can_receive_any(); }
 
  500    void enqueue(
T data) { main_socket.enqueue(data); }
 
  502    void set_default_txn(tlm::tlm_generic_payload& 
txn) { main_socket.set_default_txn(
txn); }
 
  504    void force_send(tlm::tlm_generic_payload& 
txn) { main_socket.force_send(
txn); }
 
  506    void reset() { main_socket.reset(); }
 
  509        : sc_core::sc_module(name)
 
  510        , main_socket((std::string(name) + 
"_main").
c_str())
 
  511        , 
router((std::string(name) + 
"_router").
c_str(), main_socket.name())
 
  516    const char* name() { 
return sc_module::name(); }
 
 
void set_default_txn(tlm::tlm_generic_payload &txn)
set_default_txn set transaction parameters (command, address and data_length)
Definition biflow-socket.h:290
 
void register_b_transport(MODULE *mod, void(MODULE::*cb)(tlm::tlm_generic_payload &, sc_core::sc_time &))
Register b_transport to be called whenever data is received from the socket.
Definition biflow-socket.h:227