scc 2026.07
SystemC components library
tcp4tlm_server.h
1/*******************************************************************************
2 * Copyright 2026 MINRES Technologies GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17#ifndef TLM_SCC_TCP4TLM_SERVER_H_
18#define TLM_SCC_TCP4TLM_SERVER_H_
19
20#include "rigtorp/SPSCQueue.h"
21#include "scc/async_queue.h"
22#include "scc/peq.h"
23#include "tcp4tlm/messages.h"
24#include "tcp4tlm/server.h"
25#include "tlm/scc/tlm_gp_shared.h"
26#include "tlm/scc/tlm_mm.h"
27#include <atomic>
28#include <boost/asio.hpp>
29#include <cci_configuration>
30#include <scc/report.h>
31#include <scc/utilities.h>
32#include <systemc>
33#include <tlm>
34#include <tlm_utils/simple_initiator_socket.h>
35#include <tlm_utils/simple_target_socket.h>
36#include <tlm_utils/tlm_quantumkeeper.h>
37
38namespace scc {
39
40struct tcp4tlm_server : public sc_core::sc_module, protected tcp4tlm::server<tcp4tlm::request_message, tcp4tlm::response_message> {
41 SC_HAS_PROCESS(tcp4tlm_server);
42
43 cci::cci_param<unsigned> this_host_port{"this_host_port", 32000u};
44 cci::cci_param<bool> wall_time_simulation_speed{"wall_time_simulation_speed", false};
45 cci::cci_param<bool> write_no_response{"write_no_response", false};
46 cci::cci_param<bool> no_systemc_sync{"no_systemc_sync", false};
47
48 tlm_utils::simple_initiator_socket<tcp4tlm_server, ::scc::LT> isckt;
49
50 sc_core::sc_vector<sc_core::sc_out<bool>> signals{"signals"};
51
52 tcp4tlm_server(sc_core::sc_module_name name, size_t no_of_ports = 0);
53
54 virtual ~tcp4tlm_server();
55
57 typedef std::shared_ptr<connection_type> con_ptr;
58
59 void server_send_completed(con_ptr& con, bool established = false) override {
60 if(established) {
61 con->async_read();
62 }
63 }
64
65 void server_receive_completed(con_ptr& con, const tcp4tlm::request_message* const result) override;
66
67 void start_server() {
68 using namespace std::chrono_literals;
69 server::start_server(this_host_port.get_value());
70 }
71
72 void wait4connection() {
73 using namespace std::chrono_literals;
74 // wait until con_ext becomes true. To mitigate lost notifications the wait_for wuns in a loop
75 std::unique_lock<std::mutex> lock(con_est_mtx);
76 while(!con_est.load())
77 con_est_sig.wait_for(lock, 100ms, [this]() { return con_est.load(); });
78 }
79
80 bool is_connection_established() { return con_est; }
81
82 sc_core::sc_event const& get_shutdown_event() const { return shutdown_evt; }
83
84protected:
85 using callback_task = std::packaged_task<bool(void)>;
86 struct timed_task {
87 callback_task t;
88 sc_core::sc_time timepoint;
89 };
91 scc::peq<callback_task> timed_task_que;
92 std::mutex con_est_mtx; //, gp_mtx, sync_mtx;
93 std::condition_variable con_est_sig;
94 std::atomic<bool> con_est{false};
95 sc_core::sc_event shutdown_evt;
97 unsigned long long sync;
98 void timing_thread();
99 void process_task_que();
100 void process_timed_task_que();
101 void start_of_simulation() override;
102 void end_of_simulation() override;
103 std::shared_ptr<tcp4tlm::response_message> resp_msg;
104 tlm_utils::tlm_quantumkeeper quantumkeeper;
106
107private:
108 tlm::scc::tlm_gp_shared_ptr init_gp(const tcp4tlm::BusOpMsg* const msg);
109#ifdef BOOST_ASIO_HAS_LOCAL_SOCKETS
110 tcp4tlm::request_message get_notify_endpoint_msg(boost::asio::local::stream_protocol::endpoint& ep) {
111 return tcp4tlm::make_notify_endpoint_msg(ep.path(), 0);
112 };
113#endif
114 tcp4tlm::request_message get_notify_endpoint_msg(boost::asio::ip::tcp::endpoint& ep) {
115 boost::asio::ip::address addr = ep.address();
116 return tcp4tlm::make_notify_endpoint_msg(addr.is_unspecified() ? boost::asio::ip::host_name() : addr.to_string(), ep.port());
117 }
118#ifdef GENERATE_STATISTICS
119 std::vector<unsigned long> rtto, txt, rxt;
120
121public:
122 struct statistics {
123 std::vector<unsigned long> histogram;
124 unsigned long min, max;
125 unsigned long long sum;
126 tlm_genip::addr_decoder_if& indexer;
127 unsigned long count;
128 bool print_histogram;
129 statistics(tlm_genip::addr_decoder_if& indexer_, size_t hsize, unsigned long initval)
130 : histogram(hsize, 0)
131 , min(initval)
132 , max(initval)
133 , sum(initval)
134 , indexer(indexer_)
135 , count(1)
136 , print_histogram(false) {}
137 void updateStat(unsigned long rt);
138 };
139#endif
140};
141
142#ifdef GENERATE_STATISTICS
143inline ostream& operator<<(ostream& os, const tcp4tlm_server::statistics& stat) {
144 if(stat.print_histogram)
145 for(size_t i = 0; i < stat.histogram.size() - 1; ++i)
146 os << "\t[" << stat.indexer.getBaseAddr(i) / 1000 << "us;" << stat.indexer.getBaseAddr(i + 1) / 1000 << "us)\t-> "
147 << stat.histogram[i] << endl;
148 else
149 os << stat.min << "," << stat.sum / stat.count << "," << stat.max;
150 return os;
151}
152#endif
153
154} // namespace scc
155
156#endif // TLM_SCC_TCP4TLM_SERVER_H_
The connection class provides FlatBuffers framing primitives on top of a socket.
SCC TLM utilities.
std::ostream & operator<<(std::ostream &os, log const &val)
output the textual representation of the log level
Definition report.h:133
priority event queue
Definition peq.h:42
a tlm memory manager
Definition tlm_mm.h:330