SystemC Library API Reference Manual
Reference documentation for the Simics SystemC Library.
 
Loading...
Searching...
No Matches
gasket_dispatcher.h
Go to the documentation of this file.
1/*
2 © 2020 Intel Corporation
3
4 This software and the related documents are Intel copyrighted materials, and
5 your use of them is governed by the express license under which they were
6 provided to you ("License"). Unless the License provides otherwise, you may
7 not use, modify, copy, publish, distribute, disclose or transmit this software
8 or the related documents without Intel's prior written permission.
9
10 This software and the related documents are provided as is, with no express or
11 implied warranties, other than those that are expressly stated in the License.
12*/
13
14#ifndef SIMICS_SYSTEMC_TLM2SIMICS_GASKET_DISPATCHER_H
15#define SIMICS_SYSTEMC_TLM2SIMICS_GASKET_DISPATCHER_H
16
17
19
20#include <tlm>
21#include <tlm_utils/multi_passthrough_initiator_socket.h>
22#include <tlm_utils/simple_target_socket.h>
23
24#include <map>
25#include <utility>
26#include <vector>
27
28namespace simics {
29namespace systemc {
30namespace tlm2simics {
31
33 public:
35 context_.insert(
36 std::make_pair(sc_core::sc_get_curr_simcontext(), this));
37 }
39 static void cleanCache() {
40 auto range = context_.equal_range(sc_core::sc_get_curr_simcontext());
41 for (auto it = range.first; it != range.second; ++it)
42 delete it->second;
43
44 context_.erase(sc_core::sc_get_curr_simcontext());
45 }
46
47 private:
48 static std::multimap<sc_core::sc_simcontext *,
49 GasketDispatcherBase *> context_;
50};
51
52template <unsigned int BUSWIDTH = 32,
53 typename TYPES = tlm::tlm_base_protocol_types,
54 int N = 1,
55 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
57 : public sc_core::sc_module, public GasketDispatcherBase {
58 public:
60 target_socket_.register_nb_transport_fw(
61 this, &GasketDispatcher::nb_transport_fw);
62 target_socket_.register_b_transport(
63 this, &GasketDispatcher::b_transport);
64 target_socket_.register_transport_dbg(
65 this, &GasketDispatcher::transport_dbg);
66 target_socket_.register_get_direct_mem_ptr(
67 this, &GasketDispatcher::get_direct_mem_ptr);
68 multi_initiator_.register_invalidate_direct_mem_ptr(
69 this, &GasketDispatcher::invalidate_direct_mem_ptr);
70 multi_initiator_.register_nb_transport_bw(
71 this, &GasketDispatcher::nb_transport_bw);
72 }
74 tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL> *socket,
75 const char *name,
76 const simics::ConfObjectRef &simics_obj) {
78 if (dispatchers_.find(socket) == dispatchers_.end()) {
80 sc_core::sc_gen_unique_name("GasketDispatcher"));
81 dispatchers_[socket] = dispatcher;
82 (*socket)(dispatcher->target_socket_);
83 dispatcher->simics_obj_ = simics_obj;
84 }
85
86 dispatcher = dispatchers_[socket];
87 assert(dispatcher);
89 name, simics_obj);
90
91 dispatcher->receivers_.push_back(
92 std::make_pair(dispatcher->receivers_.size(),
93 gasket));
94 gasket->bind(dispatcher->multi_initiator_);
95 return GasketInterface::Ptr(gasket);
96 }
98 for (auto it = dispatchers_.begin(); it != dispatchers_.end(); ++it) {
99 if (it->second == this) {
100 dispatchers_.erase(it);
101 return;
102 }
103 }
104 }
105
106 private:
107 tlm::tlm_sync_enum nb_transport_fw(
108 tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, // NOLINT
109 sc_core::sc_time &local_time) { // NOLINT
110 int idx = index(&trans);
111 if (idx >= 0)
112 return multi_initiator_[idx]->nb_transport_fw(trans, phase,
113 local_time);
114
115 return tlm::TLM_COMPLETED;
116 }
117 tlm::tlm_sync_enum nb_transport_bw(
118 int idx, tlm::tlm_generic_payload &trans, // NOLINT
119 tlm::tlm_phase &phase, sc_core::sc_time &local_time) { // NOLINT
120 return target_socket_->nb_transport_bw(trans, phase, local_time);
121 }
122 void b_transport(
123 tlm::tlm_generic_payload &trans, sc_core::sc_time &local_time) { // NOLINT
124 int idx = index(&trans);
125 if (idx >= 0)
126 multi_initiator_[idx]->b_transport(trans, local_time);
127 }
128 unsigned int transport_dbg(tlm::tlm_generic_payload &trans) { // NOLINT
129 int idx = index(&trans);
130 if (idx >= 0)
131 return multi_initiator_[idx]->transport_dbg(trans);
132
133 return 0;
134 }
135 void invalidate_direct_mem_ptr(int idx, sc_dt::uint64 start_range,
136 sc_dt::uint64 end_range) {
137 target_socket_->invalidate_direct_mem_ptr(start_range, end_range);
138 }
139
140 bool get_direct_mem_ptr(
141 tlm::tlm_generic_payload &trans, tlm::tlm_dmi &dmi) { // NOLINT
142 int idx = index(&trans);
143 if (idx >= 0)
144 return multi_initiator_[idx]->get_direct_mem_ptr(trans, dmi);
145
146 return false;
147 }
148
149 int index(tlm::tlm_generic_payload *trans) {
150 if ((sc_core::SC_ELABORATION |
151 sc_core::SC_BEFORE_END_OF_ELABORATION |
152 sc_core::SC_END_OF_ELABORATION) & sc_core::sc_get_status()) {
153 SIM_LOG_ERROR(simics_obj_, 0, "b_transport called before "
154 "completion of SystemC SC_END_OF_ELABORATION");
155 return -1;
156 }
157
158 if (receivers_.size() <= 0) {
159 SIM_LOG_ERROR(simics_obj_, 0, "b_transport called without "
160 "bound socket");
161 return -1;
162 }
163
164 if (receivers_.size() > 1) {
165 for (auto it = receivers_.begin(); it != receivers_.end(); ++it) {
166 TransactionHandlerInterface *handler =
167 it->second->transaction_handler();
169 handler->receiver();
170 if (receiver && receiver->probe(trans)) {
171 return it->first;
172 }
173 }
174 }
175
176 // Use first gasket as default for transactions without extensions
177 return 0;
178 }
179
180 static std::map<sc_core::sc_object*,
181 GasketDispatcher<BUSWIDTH, TYPES, N, POL> *> dispatchers_;
182
183 std::vector<std::pair<size_t, GasketInterface *> > receivers_;
184 tlm_utils::multi_passthrough_initiator_socket<
185 GasketDispatcher,
186 BUSWIDTH,
187 TYPES> multi_initiator_;
188 tlm_utils::simple_target_socket<
189 GasketDispatcher<BUSWIDTH, TYPES, N, POL>,
190 BUSWIDTH, TYPES> target_socket_;
191 simics::ConfObjectRef simics_obj_;
192};
193
194template <unsigned int BUSWIDTH,
195 typename TYPES,
196 int N,
197 sc_core::sc_port_policy POL>
198std::map<sc_core::sc_object*,
199 GasketDispatcher<BUSWIDTH, TYPES, N, POL> *>
200GasketDispatcher<BUSWIDTH, TYPES, N, POL>::dispatchers_;
201
202} // namespace tlm2simics
203} // namespace systemc
204} // namespace simics
205
206#endif
Interface implemented by the ExtensionReceiver class, used by the ExtensionDispatcher.
Definition: receiver_interface.h:27
virtual bool probe(tlm::tlm_generic_payload *payload)=0
Definition: gasket_dispatcher.h:32
GasketDispatcherBase()
Definition: gasket_dispatcher.h:34
virtual ~GasketDispatcherBase()
Definition: gasket_dispatcher.h:38
static void cleanCache()
Definition: gasket_dispatcher.h:39
Definition: gasket_dispatcher.h:57
static GasketInterface::Ptr bind(tlm::tlm_initiator_socket< BUSWIDTH, TYPES, N, POL > *socket, const char *name, const simics::ConfObjectRef &simics_obj)
Definition: gasket_dispatcher.h:73
SC_CTOR(GasketDispatcher)
Definition: gasket_dispatcher.h:59
virtual ~GasketDispatcher()
Definition: gasket_dispatcher.h:97
std::shared_ptr< GasketInterface > Ptr
Definition: gasket_interface.h:30
Implements core functionality for receiving a TLM2 transaction over a socket.
Definition: gasket.h:45
void bind(Socket &sock)
Definition: gasket.h:71
Definition: adapter.h:79