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