simple_initiator_socket.h revision 13743:62e81e25d8d5
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 "../core/sc_module.hh"
24#include "../core/sc_port.hh"
25#include "../tlm_core/2/generic_payload/gp.hh"
26#include "../tlm_core/2/interfaces/fw_bw_ifs.hh"
27#include "../tlm_core/2/sockets/initiator_socket.hh"
28#include "../tlm_core/2/sockets/target_socket.hh"
29#include "../utils/sc_report_handler.hh"
30#include "convenience_socket_bases.h"
31
32namespace tlm_utils
33{
34
35template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
36          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
37class simple_initiator_socket_b :
38    public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>,
39    protected simple_socket_base
40{
41  public:
42    typedef typename TYPES::tlm_payload_type transaction_type;
43    typedef typename TYPES::tlm_phase_type phase_type;
44    typedef tlm::tlm_sync_enum sync_enum_type;
45    typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
46    typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
47    typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type;
48
49  public:
50    static const char *
51    default_name()
52    {
53        return sc_core::sc_gen_unique_name("simple_initiator_socket");
54    }
55
56    explicit simple_initiator_socket_b(const char *n=default_name()) :
57        base_type(n), m_process(this)
58    {
59        this->m_export.bind(m_process);
60    }
61
62    void
63    register_nb_transport_bw(MODULE *mod,
64            sync_enum_type (MODULE::*cb)(transaction_type &, phase_type &,
65                sc_core::sc_time &))
66    {
67        m_process.set_transport_ptr(mod, cb);
68    }
69
70    void
71    register_invalidate_direct_mem_ptr(MODULE *mod,
72            void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
73    {
74        m_process.set_invalidate_direct_mem_ptr(mod, cb);
75    }
76
77  private:
78    class process : public tlm::tlm_bw_transport_if<TYPES>,
79                    protected convenience_socket_cb_holder
80    {
81      public:
82        typedef sync_enum_type (MODULE::*TransportPtr)(
83                transaction_type &, phase_type &, sc_core::sc_time &);
84        typedef void (MODULE::*InvalidateDirectMemPtr)(
85                sc_dt::uint64, sc_dt::uint64);
86
87        explicit process(simple_socket_base *owner) :
88            convenience_socket_cb_holder(owner), m_mod(0),
89            m_transport_ptr(0), m_invalidate_direct_mem_ptr(0)
90        {}
91
92        void
93        set_transport_ptr(MODULE *mod, TransportPtr p)
94        {
95            if (m_transport_ptr) {
96                display_warning("non-blocking callback already registered");
97                return;
98            }
99            sc_assert(!m_mod || m_mod == mod);
100            m_mod = mod;
101            m_transport_ptr = p;
102        }
103
104        void
105        set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p)
106        {
107            if (m_invalidate_direct_mem_ptr) {
108                display_warning("invalidate DMI callback already registered");
109                return;
110            }
111            sc_assert(!m_mod || m_mod == mod);
112            m_mod = mod;
113            m_invalidate_direct_mem_ptr = p;
114        }
115
116        sync_enum_type
117        nb_transport_bw(transaction_type &trans, phase_type &phase,
118                        sc_core::sc_time &t)
119        {
120            if (m_transport_ptr) {
121                // Forward call.
122                sc_assert(m_mod);
123                return (m_mod->*m_transport_ptr)(trans, phase, t);
124            }
125            display_error("no transport callback registered");
126            return tlm::TLM_COMPLETED;
127        }
128
129        void
130        invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
131                                  sc_dt::uint64 end_range)
132        {
133            if (m_invalidate_direct_mem_ptr) {
134                // Forward call.
135                sc_assert(m_mod);
136                (m_mod->*m_invalidate_direct_mem_ptr)(
137                        start_range, end_range);
138            }
139        }
140
141      private:
142        MODULE *m_mod;
143        TransportPtr m_transport_ptr;
144        InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
145    };
146
147  private:
148    const sc_core::sc_object *get_socket() const { return this; }
149
150  private:
151    process m_process;
152};
153
154template <typename MODULE, unsigned int BUSWIDTH=32,
155          typename TYPES=tlm::tlm_base_protocol_types>
156class simple_initiator_socket :
157    public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES>
158{
159    typedef simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES> socket_b;
160  public:
161    simple_initiator_socket() : socket_b() {}
162    explicit simple_initiator_socket(const char *name) : socket_b(name) {}
163};
164
165template <typename MODULE, unsigned int BUSWIDTH=32,
166          typename TYPES=tlm::tlm_base_protocol_types>
167class simple_initiator_socket_optional :
168    public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES,
169                                     sc_core::SC_ZERO_OR_MORE_BOUND>
170{
171    typedef simple_initiator_socket_b<
172        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
173  public:
174    simple_initiator_socket_optional() : socket_b() {}
175    explicit simple_initiator_socket_optional(const char *name) :
176        socket_b(name)
177    {}
178};
179
180
181// Tagged version
182
183template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
184          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
185class simple_initiator_socket_tagged_b :
186    public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>,
187    protected simple_socket_base
188{
189  public:
190    typedef typename TYPES::tlm_payload_type transaction_type;
191    typedef typename TYPES::tlm_phase_type phase_type;
192    typedef tlm::tlm_sync_enum sync_enum_type;
193    typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
194    typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
195    typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type;
196
197  public:
198    static const char *
199    default_name()
200    {
201        return sc_core::sc_gen_unique_name("simple_initiator_socket_tagged");
202    }
203
204    explicit simple_initiator_socket_tagged_b(const char *n=default_name()) :
205        base_type(n), m_process(this)
206    {
207        this->m_export.bind(m_process);
208    }
209
210    void
211    register_nb_transport_bw(MODULE *mod,
212            sync_enum_type (MODULE::*cb)(
213                int, transaction_type &, phase_type &, sc_core::sc_time &),
214            int id)
215    {
216        m_process.set_transport_ptr(mod, cb);
217        m_process.set_transport_user_id(id);
218    }
219
220    void
221    register_invalidate_direct_mem_ptr(MODULE *mod,
222            void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64), int id)
223    {
224        m_process.set_invalidate_direct_mem_ptr(mod, cb);
225        m_process.set_invalidate_dmi_user_id(id);
226    }
227
228  private:
229    class process : public tlm::tlm_bw_transport_if<TYPES>,
230                    protected convenience_socket_cb_holder
231    {
232      public:
233        typedef sync_enum_type (MODULE::*TransportPtr)(
234                int, transaction_type &, phase_type &, sc_core::sc_time &);
235        typedef void (MODULE::*InvalidateDirectMemPtr)(
236                int, sc_dt::uint64, sc_dt::uint64);
237
238        explicit process(simple_socket_base *owner) :
239            convenience_socket_cb_holder(owner), m_mod(0),
240            m_transport_ptr(0), m_invalidate_direct_mem_ptr(0),
241            m_transport_user_id(0), m_invalidate_direct_mem_user_id(0)
242        {}
243
244        void set_transport_user_id(int id) { m_transport_user_id = id; }
245        void
246        set_invalidate_dmi_user_id(int id)
247        {
248            m_invalidate_direct_mem_user_id = id;
249        }
250
251        void
252        set_transport_ptr(MODULE *mod, TransportPtr p)
253        {
254            if (m_transport_ptr) {
255                display_warning("non-blocking callback already registered");
256                return;
257            }
258            sc_assert(!m_mod || m_mod == mod);
259            m_mod = mod;
260            m_transport_ptr = p;
261        }
262
263        void
264        set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p)
265        {
266            if (m_invalidate_direct_mem_ptr) {
267                display_warning("invalidate DMI callback already registered");
268                return;
269            }
270            sc_assert(!m_mod || m_mod == mod);
271            m_mod = mod;
272            m_invalidate_direct_mem_ptr = p;
273        }
274
275        sync_enum_type
276        nb_transport_bw(transaction_type &trans, phase_type &phase,
277                        sc_core::sc_time &t)
278        {
279            if (m_transport_ptr) {
280                // Forward call.
281                sc_assert(m_mod);
282                return (m_mod->*m_transport_ptr)(
283                        m_transport_user_id, trans, phase, t);
284            }
285            display_error("no transport callback registered");
286            return tlm::TLM_COMPLETED;
287        }
288
289        void
290        invalidate_direct_mem_ptr(
291                sc_dt::uint64 start_range, sc_dt::uint64 end_range)
292        {
293            if (m_invalidate_direct_mem_ptr) {
294                // Forward call.
295                sc_assert(m_mod);
296                (m_mod->*m_invalidate_direct_mem_ptr)(
297                        m_invalidate_direct_mem_user_id,
298                        start_range, end_range);
299            }
300        }
301
302      private:
303        MODULE *m_mod;
304        TransportPtr m_transport_ptr;
305        InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
306        int m_transport_user_id;
307        int m_invalidate_direct_mem_user_id;
308    };
309
310  private:
311    const sc_core::sc_object *get_socket() const { return this; }
312
313  private:
314    process m_process;
315};
316
317template <typename MODULE, unsigned int BUSWIDTH=32,
318          typename TYPES=tlm::tlm_base_protocol_types>
319class simple_initiator_socket_tagged :
320    public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
321{
322    typedef simple_initiator_socket_tagged_b<
323        MODULE, BUSWIDTH, TYPES> socket_b;
324  public:
325    simple_initiator_socket_tagged() : socket_b() {}
326    explicit simple_initiator_socket_tagged(const char *name) :
327        socket_b(name)
328    {}
329};
330
331template <typename MODULE, unsigned int BUSWIDTH=32,
332          typename TYPES=tlm::tlm_base_protocol_types>
333class simple_initiator_socket_tagged_optional :
334    public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES,
335                                            sc_core::SC_ZERO_OR_MORE_BOUND>
336{
337    typedef simple_initiator_socket_tagged_b<
338        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
339  public:
340    simple_initiator_socket_tagged_optional() : socket_b() {}
341    explicit simple_initiator_socket_tagged_optional(const char *name) :
342        socket_b(name)
343    {}
344};
345
346} // namespace tlm_utils
347
348#endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ */
349