#include #include "utils/log.h" using sc_core::sc_export; using sc_core::sc_interface; using sc_core::sc_module; using sc_core::sc_module_name; using sc_core::SC_NS; using sc_core::sc_port; // -- INTERFACES --------------------------------------------------------------- struct fwd_if : sc_interface { virtual void fwd(const char* msg) = 0; }; struct bwd_if : sc_interface { virtual void bwd(const char* msg) = 0; }; // -- INITIATOR SOCKET --------------------------------------------------------- // An initiator socket provides its owner access to a FWD_IF implementation. The // initiator socket itself must be bound against a BWD_IF implementation, // offering the BWD_IF implementation to the target socket that can be bound // against the initiator socket. // // Effectively the initiator socket is a sc_port / sc_export pair, using the // sc_port to access the FWD_IF and the sc_export to offer the BWD_IF // implementation. struct initiator_socket : sc_export { sc_port p_fwd; fwd_if* operator->() { return p_fwd.operator->(); } }; // -- TARGET SOCKET ------------------------------------------------------------ // A target socket provides its owner access to a BWD_IF implementation. The // target socket itself must be bound against a FWD_IF implementation, // offering the FWD_IF implementation to the initiator socket that can be bound // against the target socket. // // Effectively the target socket is a sc_port / sc_export pair, using the // sc_port to access the BWD_IF and the sc_export to offer the FWD_IF // implementation. struct target_socket : sc_export { sc_port p_bwd; void bind(initiator_socket& init) { // Bind the sc_port / sc_export pairs between the initiator and target // socket. // Initiator:sc_port -> Target:sc_export. init.p_fwd(*this); // Target:sc_port -> Initiator:sc_export. p_bwd(init); } bwd_if* operator->() { return p_bwd.operator->(); } }; // -- INITIATOR ---------------------------------------------------------------- struct initiator : public sc_module, public bwd_if { SC_HAS_PROCESS(initiator); initiator_socket p_sock; explicit initiator(sc_module_name nm) : sc_module(std::move(nm)) { p_sock(*this); SC_THREAD(work); } private: virtual void bwd(const char* msg) override { LOGM("%s", msg); } void work() { sc_core::wait(10, SC_NS); p_sock->fwd("moose"); } }; // -- TARGET ------------------------------------------------------------------- struct target : public sc_module, public fwd_if { SC_HAS_PROCESS(target); target_socket p_sock; explicit target(sc_module_name nm) : sc_module(std::move(nm)) { p_sock(*this); } private: virtual void fwd(const char* msg) override { LOGM("%s", msg); p_sock->bwd("meeh"); } }; // -- SC_MAIN ------------------------------------------------------------------ extern "C" int sc_main(int, char*[]) { initiator I("initiator"); target T("target"); // Bind the initiator and target sockets. T.p_sock.bind(I.p_sock); sc_core::sc_start(); return 0; }