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