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_VALUE } 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);
99 txn.set_streaming_width(
sending);
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);
110 sc_assert(txn.get_data_length() ==
sizeof(ctrl));
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);
131 case ctrl::INFINITE_VALUE:
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;
177 : sc_core::sc_module(name)
178 , input_socket((std::
string(name) +
"_input_socket").
c_str())
179 , output_socket((std::
string(name) +
"_output_socket").
c_str())
180 , input_control_socket((std::
string(name) +
"_input_socket_control").
c_str())
181 , output_control_socket((std::
string(name) +
"_output_socket_control").
c_str())
189 output_control_socket.register_b_transport(
this, &biflow_socket::initiator_ctrl);
190 m_send_event.async_detach_suspending();
193 tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_input_socket() {
return input_socket; }
194 tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_output_socket() {
return output_socket; };
195 tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_input_control_socket() {
return input_control_socket; };
196 tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_output_control_socket() {
return output_control_socket; };
207 other.new_bind(*
this);
208 output_socket.bind(
other.get_input_socket());
209 input_control_socket.bind(
other.get_output_control_socket());
210 other.get_output_socket().bind(input_socket);
211 other.get_input_control_socket().bind(output_control_socket);
228 input_socket.register_b_transport(mod,
cb);
239 c.cmd = ctrl::DELTA_CHANGE;
255 c.cmd = ctrl::ABSOLUTE_VALUE;
266 c.cmd = ctrl::INFINITE_VALUE;
279 std::lock_guard<std::mutex>
guard(m_mutex);
280 m_queue.push_back(data);
281 m_send_event.notify();
291 if (!m_txn) m_txn = std::make_unique<tlm::tlm_generic_payload>();
292 m_txn->deep_copy_from(txn);
302 sc_core::sc_time delay;
303 output_socket->b_transport(txn, delay);
313 std::lock_guard<std::mutex>
guard(m_mutex);
331 class remote :
public sc_core::sc_object
333 sc_core::sc_vector<remote>& m_remotes;
338 remote* m_sendto =
nullptr;
340 void route_data(tlm::tlm_generic_payload& txn, sc_core::sc_time&
t)
342 T* ptr = (
T*)txn.get_data_ptr();
344 for (
auto& remote : m_remotes) {
345 if (&remote !=
this && (!m_sendto || m_sendto == &remote)) {
347 remote.socket.set_default_txn(txn);
348 for (
int i = 0;
i < txn.get_data_length();
i++) {
350 memcpy(&data, &(ptr[
i]),
sizeof(
T));
351 remote.socket.enqueue(data);
356 SCP_WARN(())(
"Should have been sent - sendto {}", m_sendto->name());
360 remote(sc_core::sc_module_name name, sc_core::sc_vector<struct remote>& r): socket(name), m_remotes(r)
362 socket.register_b_transport(
this, &remote::route_data);
365 void set_sendto(remote* s) { m_sendto = s; }
368 sc_core::sc_vector<remote> m_remotes;
372 cci::cci_param<std::string> p_sendto;
373 remote* m_sendto =
nullptr;
377 if (!p_sendto.get_value().empty()) {
379 SCP_WARN(())(
"{} sendto {}", remote.name(), m_sendto->name());
380 remote.set_sendto(m_sendto);
381 }
else if (std::string(
other.name()).find(p_sendto) == 0) {
383 SCP_WARN(())(
"found sendto {}", m_sendto->name());
384 for (
auto& r : m_remotes) {
386 SCP_WARN(())(
"{} sendto {}", r.name(), m_sendto->name());
387 r.set_sendto(m_sendto);
391 SCP_WARN(())(
"{} is not sendto {}",
other.name(), p_sendto.get_value());
399 m_remotes.emplace_back(m_remotes);
400 auto& remote = m_remotes[m_remotes.size() - 1];
401 binding = &(remote.socket);
402 binding->new_bind(
other);
403 sendto_setup(
other, remote);
408 binding->bind_done();
409 binding->can_receive_any();
415 SCP_TRACE(())(
"Biflow Router {} binding to {}", name(),
other.name());
416 m_remotes.emplace_back(m_remotes);
418 auto& remote = m_remotes[m_remotes.size() - 1];
419 binding = &(remote.socket);
421 binding->bind(
other);
422 binding->can_receive_any();
425 sendto_setup(
other, remote);
428 tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_input_socket()
431 return binding->get_input_socket();
433 tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_output_socket()
436 return binding->get_output_socket();
438 tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_input_control_socket()
441 return binding->get_input_control_socket();
443 tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_output_control_socket()
446 return binding->get_output_control_socket();
455 enum { DELTA_CHANGE, ABSOLUTE_VALUE, INFINITE_VALUE } cmd;
459 : sc_core::sc_module(name)
460 , m_remotes(
"remote_sockets")
461 , p_sendto(
"sendto",
sendto,
"Router all sent data to this port")
466 const char* name() {
return sc_module::name(); }
477 tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_input_socket() {
return router.get_input_socket(); }
478 tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_output_socket() {
return router.get_output_socket(); }
479 tlm::tlm_initiator_socket<DEFAULT_TLM_BUSWIDTH>& get_input_control_socket()
481 return router.get_input_control_socket();
483 tlm::tlm_target_socket<DEFAULT_TLM_BUSWIDTH>& get_output_control_socket()
485 return router.get_output_control_socket();
488 void bind_done() {
router.bind_done(); }
491 void register_b_transport(
MODULE* mod,
void (
MODULE::*
cb)(tlm::tlm_generic_payload&, sc_core::sc_time&))
493 main_socket.register_b_transport(mod,
cb);
495 void can_receive_more(
int i) { main_socket.can_receive_more(
i); }
496 void can_receive_set(
int i) { main_socket.can_receive_set(
i); }
497 void can_receive_any() { main_socket.can_receive_any(); }
499 void enqueue(
T data) { main_socket.enqueue(data); }
501 void set_default_txn(tlm::tlm_generic_payload& txn) { main_socket.set_default_txn(txn); }
503 void force_send(tlm::tlm_generic_payload& txn) { main_socket.force_send(txn); }
505 void reset() { main_socket.reset(); }
508 : sc_core::sc_module(name)
509 , main_socket((std::string(name) +
"_main").
c_str())
510 ,
router((std::string(name) +
"_router").
c_str(), main_socket.name())
515 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:289
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:226