simple_initiator_socket.h revision 13513:bbf275465d3d
1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20#ifndef __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__
21#define __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__
22
23#include <tlm>
24
25#include "tlm_utils/convenience_socket_bases.h"
26
27namespace tlm_utils
28{
29
30template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
31          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
32class simple_initiator_socket_b :
33    public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>,
34    protected simple_socket_base
35{
36  public:
37    typedef typename TYPES::tlm_payload_type transaction_type;
38    typedef typename TYPES::tlm_phase_type phase_type;
39    typedef tlm::tlm_sync_enum sync_enum_type;
40    typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
41    typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
42    typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type;
43
44  public:
45    static const char *
46    default_name()
47    {
48        return sc_core::sc_gen_unique_name("simple_initiator_socket");
49    }
50
51    explicit simple_initiator_socket_b(const char *n=default_name()) :
52        base_type(n), m_process(this)
53    {
54        this->m_export.bind(m_process);
55    }
56
57    void
58    register_nb_transport_bw(MODULE *mod,
59            sync_enum_type (MODULE::*cb)(transaction_type &, phase_type &,
60                sc_core::sc_time &))
61    {
62        m_process.set_transport_ptr(mod, cb);
63    }
64
65    void
66    register_invalidate_direct_mem_ptr(MODULE *mod,
67            void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
68    {
69        m_process.set_invalidate_direct_mem_ptr(mod, cb);
70    }
71
72  private:
73    class process : public tlm::tlm_bw_transport_if<TYPES>,
74                    protected convenience_socket_cb_holder
75    {
76      public:
77        typedef sync_enum_type (MODULE::*TransportPtr)(
78                transaction_type &, phase_type &, sc_core::sc_time &);
79        typedef void (MODULE::*InvalidateDirectMemPtr)(
80                sc_dt::uint64, sc_dt::uint64);
81
82        explicit process(simple_socket_base *owner) :
83            convenience_socket_cb_holder(owner), m_mod(0),
84            m_transport_ptr(0), m_invalidate_direct_mem_ptr(0)
85        {}
86
87        void
88        set_transport_ptr(MODULE *mod, TransportPtr p)
89        {
90            if (m_transport_ptr) {
91                display_warning("non-blocking callback already registered");
92                return;
93            }
94            sc_assert(!m_mod || m_mod == mod);
95            m_mod = mod;
96            m_transport_ptr = p;
97        }
98
99        void
100        set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p)
101        {
102            if (m_invalidate_direct_mem_ptr) {
103                display_warning("invalidate DMI callback already registered");
104                return;
105            }
106            sc_assert(!m_mod || m_mod == mod);
107            m_mod = mod;
108            m_invalidate_direct_mem_ptr = p;
109        }
110
111        sync_enum_type
112        nb_transport_bw(transaction_type &trans, phase_type &phase,
113                        sc_core::sc_time &t)
114        {
115            if (m_transport_ptr) {
116                // Forward call.
117                sc_assert(m_mod);
118                return (m_mod->*m_transport_ptr)(trans, phase, t);
119            }
120            display_error("no transport callback registered");
121            return tlm::TLM_COMPLETED;
122        }
123
124        void
125        invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
126                                  sc_dt::uint64 end_range)
127        {
128            if (m_invalidate_direct_mem_ptr) {
129                // Forward call.
130                sc_assert(m_mod);
131                (m_mod->*m_invalidate_direct_mem_ptr)(
132                        start_range, end_range);
133            }
134        }
135
136      private:
137        MODULE *m_mod;
138        TransportPtr m_transport_ptr;
139        InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
140    };
141
142  private:
143    const sc_core::sc_object *get_socket() const { return this; }
144
145  private:
146    process m_process;
147};
148
149template <typename MODULE, unsigned int BUSWIDTH=32,
150          typename TYPES=tlm::tlm_base_protocol_types>
151class simple_initiator_socket :
152    public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES>
153{
154    typedef simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES> socket_b;
155  public:
156    simple_initiator_socket() : socket_b() {}
157    explicit simple_initiator_socket(const char *name) : socket_b(name) {}
158};
159
160template <typename MODULE, unsigned int BUSWIDTH=32,
161          typename TYPES=tlm::tlm_base_protocol_types>
162class simple_initiator_socket_optional :
163    public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES,
164                                     sc_core::SC_ZERO_OR_MORE_BOUND>
165{
166    typedef simple_initiator_socket_b<
167        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
168  public:
169    simple_initiator_socket_optional() : socket_b() {}
170    explicit simple_initiator_socket_optional(const char *name) :
171        socket_b(name)
172    {}
173};
174
175
176// Tagged version
177
178template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
179          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
180class simple_initiator_socket_tagged_b :
181    public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>,
182    protected simple_socket_base
183{
184  public:
185    typedef typename TYPES::tlm_payload_type transaction_type;
186    typedef typename TYPES::tlm_phase_type phase_type;
187    typedef tlm::tlm_sync_enum sync_enum_type;
188    typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
189    typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
190    typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type;
191
192  public:
193    static const char *
194    default_name()
195    {
196        return sc_core::sc_gen_unique_name("simple_initiator_socket_tagged");
197    }
198
199    explicit simple_initiator_socket_tagged_b(const char *n=default_name()) :
200        base_type(n), m_process(this)
201    {
202        this->m_export.bind(m_process);
203    }
204
205    void
206    register_nb_transport_bw(MODULE *mod,
207            sync_enum_type (MODULE::*cb)(
208                int, transaction_type &, phase_type &, sc_core::sc_time &),
209            int id)
210    {
211        m_process.set_transport_ptr(mod, cb);
212        m_process.set_transport_user_id(id);
213    }
214
215    void
216    register_invalidate_direct_mem_ptr(MODULE *mod,
217            void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64), int id)
218    {
219        m_process.set_invalidate_direct_mem_ptr(mod, cb);
220        m_process.set_invalidate_dmi_user_id(id);
221    }
222
223  private:
224    class process : public tlm::tlm_bw_transport_if<TYPES>,
225                    protected convenience_socket_cb_holder
226    {
227      public:
228        typedef sync_enum_type (MODULE::*TransportPtr)(
229                int, transaction_type &, phase_type &, sc_core::sc_time &);
230        typedef void (MODULE::*InvalidateDirectMemPtr)(
231                int, sc_dt::uint64, sc_dt::uint64);
232
233        explicit process(simple_socket_base *owner) :
234            convenience_socket_cb_holder(owner), m_mod(0),
235            m_transport_ptr(0), m_invalidate_direct_mem_ptr(0),
236            m_transport_user_id(0), m_invalidate_direct_mem_user_id(0)
237        {}
238
239        void set_transport_user_id(int id) { m_transport_user_id = id; }
240        void
241        set_invalidate_dmi_user_id(int id)
242        {
243            m_invalidate_direct_mem_user_id = id;
244        }
245
246        void
247        set_transport_ptr(MODULE *mod, TransportPtr p)
248        {
249            if (m_transport_ptr) {
250                display_warning("non-blocking callback already registered");
251                return;
252            }
253            sc_assert(!m_mod || m_mod == mod);
254            m_mod = mod;
255            m_transport_ptr = p;
256        }
257
258        void
259        set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p)
260        {
261            if (m_invalidate_direct_mem_ptr) {
262                display_warning("invalidate DMI callback already registered");
263                return;
264            }
265            sc_assert(!m_mod || m_mod == mod);
266            m_mod = mod;
267            m_invalidate_direct_mem_ptr = p;
268        }
269
270        sync_enum_type
271        nb_transport_bw(transaction_type &trans, phase_type &phase,
272                        sc_core::sc_time &t)
273        {
274            if (m_transport_ptr) {
275                // Forward call.
276                sc_assert(m_mod);
277                return (m_mod->*m_transport_ptr)(
278                        m_transport_user_id, trans, phase, t);
279            }
280            display_error("no transport callback registered");
281            return tlm::TLM_COMPLETED;
282        }
283
284        void
285        invalidate_direct_mem_ptr(
286                sc_dt::uint64 start_range, sc_dt::uint64 end_range)
287        {
288            if (m_invalidate_direct_mem_ptr) {
289                // Forward call.
290                sc_assert(m_mod);
291                (m_mod->*m_invalidate_direct_mem_ptr)(
292                        m_invalidate_direct_mem_user_id,
293                        start_range, end_range);
294            }
295        }
296
297      private:
298        MODULE *m_mod;
299        TransportPtr m_transport_ptr;
300        InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
301        int m_transport_user_id;
302        int m_invalidate_direct_mem_user_id;
303    };
304
305  private:
306    const sc_core::sc_object *get_socket() const { return this; }
307
308  private:
309    process m_process;
310};
311
312template <typename MODULE, unsigned int BUSWIDTH=32,
313          typename TYPES=tlm::tlm_base_protocol_types>
314class simple_initiator_socket_tagged :
315    public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
316{
317    typedef simple_initiator_socket_tagged_b<
318        MODULE, BUSWIDTH, TYPES> socket_b;
319  public:
320    simple_initiator_socket_tagged() : socket_b() {}
321    explicit simple_initiator_socket_tagged(const char *name) :
322        socket_b(name)
323    {}
324};
325
326template <typename MODULE, unsigned int BUSWIDTH=32,
327          typename TYPES=tlm::tlm_base_protocol_types>
328class simple_initiator_socket_tagged_optional :
329    public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES,
330                                            sc_core::SC_ZERO_OR_MORE_BOUND>
331{
332    typedef simple_initiator_socket_tagged_b<
333        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
334  public:
335    simple_initiator_socket_tagged_optional() : socket_b() {}
336    explicit simple_initiator_socket_tagged_optional(const char *name) :
337        socket_b(name)
338    {}
339};
340
341} // namespace tlm_utils
342
343#endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ */
344