gp.hh (13521:74fa3ac44057) gp.hh (13586:008fe87c1ad4)
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_CORE_2_GENERIC_PAYLOAD_GP_HH__
21#define __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__
22
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_CORE_2_GENERIC_PAYLOAD_GP_HH__
21#define __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__
22
23#include <systemc>
24#include <typeinfo> // std::type_info
25
23#include <typeinfo> // std::type_info
24
26#include "tlm_core/2/generic_payload/array.hh"
25#include "../../../utils/sc_report_handler.hh" // sc_assert
26#include "array.hh"
27
28namespace tlm
29{
30
31class tlm_generic_payload;
32
33class tlm_mm_interface
34{
35 public:
36 virtual void free(tlm_generic_payload *) = 0;
37 virtual ~tlm_mm_interface() {}
38};
39
40//---------------------------------------------------------------------------
41// Classes and helpers for the extension mechanism
42//---------------------------------------------------------------------------
43// Helper function:
44unsigned int max_num_extensions();
45
46// This class can be used for storing pointers to the extension classes, used
47// in tlm_generic_payload:
48class tlm_extension_base
49{
50 public:
51 virtual tlm_extension_base *clone() const = 0;
52 virtual void free() { delete this; }
53 virtual void copy_from(tlm_extension_base const &) = 0;
54 protected:
55 virtual ~tlm_extension_base() {}
56 static unsigned int register_extension(const std::type_info &);
57};
58
59// Base class for all extension classes, derive your extension class in
60// the following way:
61// class my_extension : public tlm_extension<my_extension> { ...
62// This triggers proper extension registration during C++ static
63// contruction time. my_extension::ID will hold the unique index in the
64// tlm_generic_payload::m_extensions array.
65template <typename T>
66class tlm_extension : public tlm_extension_base
67{
68 public:
69 virtual tlm_extension_base *clone() const = 0;
70 virtual void copy_from(tlm_extension_base const &ext) = 0;
71 virtual ~tlm_extension() {}
72 const static unsigned int ID;
73};
74
75template <typename T>
76const unsigned int tlm_extension<T>::ID =
77 tlm_extension_base::register_extension(typeid(T));
78
79//---------------------------------------------------------------------------
80// enumeration types
81//---------------------------------------------------------------------------
82enum tlm_command
83{
84 TLM_READ_COMMAND,
85 TLM_WRITE_COMMAND,
86 TLM_IGNORE_COMMAND
87};
88
89enum tlm_response_status
90{
91 TLM_OK_RESPONSE = 1,
92 TLM_INCOMPLETE_RESPONSE = 0,
93 TLM_GENERIC_ERROR_RESPONSE = -1,
94 TLM_ADDRESS_ERROR_RESPONSE = -2,
95 TLM_COMMAND_ERROR_RESPONSE = -3,
96 TLM_BURST_ERROR_RESPONSE = -4,
97 TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
98};
99
100enum tlm_gp_option
101{
102 TLM_MIN_PAYLOAD,
103 TLM_FULL_PAYLOAD,
104 TLM_FULL_PAYLOAD_ACCEPTED
105};
106
107#define TLM_BYTE_DISABLED 0x0
108#define TLM_BYTE_ENABLED 0xff
109
110//---------------------------------------------------------------------------
111// The generic payload class:
112//---------------------------------------------------------------------------
113
114extern template class tlm_array<tlm_extension_base *>;
115
116class tlm_generic_payload
117{
118 public:
119 tlm_generic_payload();
120 explicit tlm_generic_payload(tlm_mm_interface *mm);
121
122 void
123 acquire()
124 {
125 sc_assert(m_mm != 0);
126 m_ref_count++;
127 }
128
129 void
130 release()
131 {
132 sc_assert(m_mm != 0 && m_ref_count > 0);
133 if (--m_ref_count == 0)
134 m_mm->free(this);
135 }
136
137 int get_ref_count() const { return m_ref_count; }
138
139 void set_mm(tlm_mm_interface *mm) { m_mm = mm; }
140 bool has_mm() const { return m_mm != 0; }
141
142 void reset();
143
144 private:
145 // Disabled copy ctor and assignment operator.
146 tlm_generic_payload(const tlm_generic_payload &x);
147 tlm_generic_payload &operator = (const tlm_generic_payload &x);
148
149 public:
150 // Non-virtual deep-copying of the object.
151 void deep_copy_from(const tlm_generic_payload &other);
152
153 // To update the state of the original generic payload from a deep copy.
154 // Assumes that "other" was created from the original by calling
155 // deep_copy_from Argument use_byte_enable_on_read determines whether to
156 // use or ignores byte enables when copying back the data array on a read
157 // command.
158
159 void update_original_from(const tlm_generic_payload &other,
160 bool use_byte_enable_on_read=true);
161
162 void update_extensions_from(const tlm_generic_payload &other);
163
164 // Free all extensions. Useful when reusing a cloned transaction that
165 // doesn't have memory manager. Normal and sticky extensions are freed and
166 // extension array cleared.
167 void free_all_extensions();
168
169 virtual ~tlm_generic_payload();
170
171 //----------------
172 // API (including setters & getters).
173 //---------------
174
175 // Command related method.
176 bool is_read() const { return (m_command == TLM_READ_COMMAND); }
177 void set_read() { m_command = TLM_READ_COMMAND; }
178 bool is_write() const { return (m_command == TLM_WRITE_COMMAND); }
179 void set_write() { m_command = TLM_WRITE_COMMAND; }
180 tlm_command get_command() const { return m_command; }
181 void set_command(const tlm_command command) { m_command = command; }
182
183 // Address related methods.
184 sc_dt::uint64 get_address() const { return m_address; }
185 void set_address(const sc_dt::uint64 address) { m_address = address; }
186
187 // Data related methods.
188 unsigned char *get_data_ptr() const { return m_data; }
189 void set_data_ptr(unsigned char *data) { m_data = data; }
190
191 // Transaction length (in bytes) related methods.
192 unsigned int get_data_length() const { return m_length; }
193 void set_data_length(const unsigned int length) { m_length = length; }
194
195 // Response status related methods.
196 bool is_response_ok() const { return (m_response_status > 0); }
197 bool is_response_error() const { return (m_response_status <= 0); }
198 tlm_response_status
199 get_response_status() const
200 {
201 return m_response_status;
202 }
203 void
204 set_response_status(const tlm_response_status response_status)
205 {
206 m_response_status = response_status;
207 }
208 std::string get_response_string() const;
209
210 // Streaming related methods.
211 unsigned int get_streaming_width() const { return m_streaming_width; }
212 void
213 set_streaming_width(const unsigned int streaming_width)
214 {
215 m_streaming_width = streaming_width;
216 }
217
218 // Byte enable related methods.
219 unsigned char *get_byte_enable_ptr() const { return m_byte_enable; }
220 void
221 set_byte_enable_ptr(unsigned char *byte_enable)
222 {
223 m_byte_enable = byte_enable;
224 }
225 unsigned int
226 get_byte_enable_length() const
227 {
228 return m_byte_enable_length;
229 }
230 void
231 set_byte_enable_length(const unsigned int byte_enable_length)
232 {
233 m_byte_enable_length = byte_enable_length;
234 }
235
236 // This is the "DMI-hint" a slave can set this to true if it
237 // wants to indicate that a DMI request would be supported:
238 void
239 set_dmi_allowed(bool dmi_allowed)
240 {
241 m_dmi = dmi_allowed;
242 }
243 bool
244 is_dmi_allowed() const
245 {
246 return m_dmi;
247 }
248
249 // Use full set of attributes in DMI/debug?
250 tlm_gp_option get_gp_option() const { return m_gp_option; }
251 void set_gp_option(const tlm_gp_option gp_opt) { m_gp_option = gp_opt; }
252
253 private:
254 /* --------------------------------------------------------------------- */
255 /* Generic Payload attributes: */
256 /* --------------------------------------------------------------------- */
257 /* - m_command : Type of transaction. Three values supported: */
258 /* - TLM_WRITE_COMMAND */
259 /* - TLM_READ_COMMAND */
260 /* - TLM_IGNORE_COMMAND */
261 /* - m_address : Transaction base address (byte-addressing). */
262 /* - m_data : When m_command = TLM_WRITE_COMMAND contains a */
263 /* pointer to the data to be written in the target.*/
264 /* When m_command = TLM_READ_COMMAND contains a */
265 /* pointer where to copy the data read from the */
266 /* target. */
267 /* - m_length : Total number of bytes of the transaction. */
268 /* - m_response_status : This attribute indicates whether an error has */
269 /* occurred during the transaction. */
270 /* Values supported are: */
271 /* - TLM_OK_RESP */
272 /* - TLM_INCOMPLETE_RESP */
273 /* - TLM_GENERIC_ERROR_RESP */
274 /* - TLM_ADDRESS_ERROR_RESP */
275 /* - TLM_COMMAND_ERROR_RESP */
276 /* - TLM_BURST_ERROR_RESP */
277 /* - TLM_BYTE_ENABLE_ERROR_RESP */
278 /* */
279 /* - m_byte_enable : It can be used to create burst transfers where */
280 /* the address increment between each beat is greater */
281 /* than the word length of each beat, or to place */
282 /* words in selected byte lanes of a bus. */
283 /* - m_byte_enable_length : For a read or a write command, the target */
284 /* interpret the byte enable length attribute as the */
285 /* number of elements in the bytes enable array. */
286 /* - m_streaming_width : */
287 /* --------------------------------------------------------------------- */
288
289 sc_dt::uint64 m_address;
290 tlm_command m_command;
291 unsigned char *m_data;
292 unsigned int m_length;
293 tlm_response_status m_response_status;
294 bool m_dmi;
295 unsigned char *m_byte_enable;
296 unsigned int m_byte_enable_length;
297 unsigned int m_streaming_width;
298 tlm_gp_option m_gp_option;
299
300 public:
301 /* --------------------------------------------------------------------- */
302 /* Dynamic extension mechanism: */
303 /* --------------------------------------------------------------------- */
304 /* The extension mechanism is intended to enable initiator modules to */
305 /* optionally and transparently add data fields to the */
306 /* tlm_generic_payload. Target modules are free to check for extensions */
307 /* and may or may not react to the data in the extension fields. The */
308 /* definition of the extensions' semantics is solely in the */
309 /* responsibility of the user. */
310 /* */
311 /* The following rules apply: */
312 /* */
313 /* - Every extension class must be derived from tlm_extension, e.g.: */
314 /* class my_extension : public tlm_extension<my_extension> { ... } */
315 /* */
316 /* - A tlm_generic_payload object should be constructed after C++ */
317 /* static initialization time. This way it is guaranteed that the */
318 /* extension array is of sufficient size to hold all possible */
319 /* extensions. Alternatively, the initiator module can enforce a valid */
320 /* extension array size by calling the resize_extensions() method */
321 /* once before the first transaction with the payload object is */
322 /* initiated. */
323 /* */
324 /* - Initiators should use the the set_extension(e) or clear_extension(e)*/
325 /* methods for manipulating the extension array. The type of the */
326 /* argument must be a pointer to the specific registered extension */
327 /* type (my_extension in the above example) and is used to */
328 /* automatically locate the appropriate index in the array. */
329 /* */
330 /* - Targets can check for a specific extension by calling */
331 /* get_extension(e). e will point to zero if the extension is not */
332 /* present. */
333 /* */
334 /* --------------------------------------------------------------------- */
335
336 // Stick the pointer to an extension into the vector, return the
337 // previous value:
338 template <typename T>
339 T *
340 set_extension(T *ext)
341 {
342 return static_cast<T *>(set_extension(T::ID, ext));
343 }
344
345 // Non-templatized version with manual index:
346 tlm_extension_base *set_extension(
347 unsigned int index, tlm_extension_base *ext);
348
349 // Stick the pointer to an extension into the vector, return the
350 // previous value and schedule its release.
351 template <typename T>
352 T *
353 set_auto_extension(T *ext)
354 {
355 return static_cast<T *>(set_auto_extension(T::ID, ext));
356 }
357
358 // Non-templatized version with manual index:
359 tlm_extension_base *set_auto_extension(
360 unsigned int index, tlm_extension_base *ext);
361
362 // Check for an extension, ext will point to 0 if not present.
363 template <typename T>
364 void get_extension(T *& ext) const { ext = get_extension<T>(); }
365 template <typename T>
366 T *
367 get_extension() const
368 {
369 return static_cast<T*>(get_extension(T::ID));
370 }
371 // Non-templatized version with manual index:
372 tlm_extension_base *get_extension(unsigned int index) const;
373
374 // This call just removes the extension from the txn but does not
375 // call free() or tells the MM to do so it return false if there was
376 // active MM so you are now in an unsafe situation recommended use:
377 // when 100% sure there is no MM.
378 template <typename T>
379 void clear_extension(const T *ext) { clear_extension<T>(); }
380
381 // This call just removes the extension from the txn but does not
382 // call free() or tells the MM to do so it return false if there was
383 // active MM so you are now in an unsafe situation recommended use: when
384 // 100% sure there is no MM.
385 template <typename T>
386 void clear_extension() { clear_extension(T::ID); }
387
388 // This call removes the extension from the txn and does call free() or
389 // tells the MM to do so when the txn is finally done recommended use:
390 // when not sure there is no MM.
391 template <typename T>
392 void release_extension(T *ext)
393 {
394 release_extension<T>();
395 }
396
397 // This call removes the extension from the txn and does call free() or
398 // tells the MM to do so when the txn is finally done recommended use:
399 // when not sure there is no MM
400 template <typename T>
401 void release_extension()
402 {
403 release_extension(T::ID);
404 }
405
406 private:
407 // Non-templatized version with manual index
408 void clear_extension(unsigned int index);
409 // Non-templatized version with manual index
410 void release_extension(unsigned int index);
411
412 public:
413 // Make sure the extension array is large enough. Can be called once by
414 // an initiator module (before issuing the first transaction) to make
415 // sure that the extension array is of correct size. This is only needed
416 // if the initiator cannot guarantee that the generic payload object is
417 // allocated after C++ static construction time.
418 void resize_extensions();
419
420 private:
421 tlm_array<tlm_extension_base *> m_extensions;
422 tlm_mm_interface *m_mm;
423 unsigned int m_ref_count;
424};
425
426} // namespace tlm
427
428#endif /* __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__ */
27
28namespace tlm
29{
30
31class tlm_generic_payload;
32
33class tlm_mm_interface
34{
35 public:
36 virtual void free(tlm_generic_payload *) = 0;
37 virtual ~tlm_mm_interface() {}
38};
39
40//---------------------------------------------------------------------------
41// Classes and helpers for the extension mechanism
42//---------------------------------------------------------------------------
43// Helper function:
44unsigned int max_num_extensions();
45
46// This class can be used for storing pointers to the extension classes, used
47// in tlm_generic_payload:
48class tlm_extension_base
49{
50 public:
51 virtual tlm_extension_base *clone() const = 0;
52 virtual void free() { delete this; }
53 virtual void copy_from(tlm_extension_base const &) = 0;
54 protected:
55 virtual ~tlm_extension_base() {}
56 static unsigned int register_extension(const std::type_info &);
57};
58
59// Base class for all extension classes, derive your extension class in
60// the following way:
61// class my_extension : public tlm_extension<my_extension> { ...
62// This triggers proper extension registration during C++ static
63// contruction time. my_extension::ID will hold the unique index in the
64// tlm_generic_payload::m_extensions array.
65template <typename T>
66class tlm_extension : public tlm_extension_base
67{
68 public:
69 virtual tlm_extension_base *clone() const = 0;
70 virtual void copy_from(tlm_extension_base const &ext) = 0;
71 virtual ~tlm_extension() {}
72 const static unsigned int ID;
73};
74
75template <typename T>
76const unsigned int tlm_extension<T>::ID =
77 tlm_extension_base::register_extension(typeid(T));
78
79//---------------------------------------------------------------------------
80// enumeration types
81//---------------------------------------------------------------------------
82enum tlm_command
83{
84 TLM_READ_COMMAND,
85 TLM_WRITE_COMMAND,
86 TLM_IGNORE_COMMAND
87};
88
89enum tlm_response_status
90{
91 TLM_OK_RESPONSE = 1,
92 TLM_INCOMPLETE_RESPONSE = 0,
93 TLM_GENERIC_ERROR_RESPONSE = -1,
94 TLM_ADDRESS_ERROR_RESPONSE = -2,
95 TLM_COMMAND_ERROR_RESPONSE = -3,
96 TLM_BURST_ERROR_RESPONSE = -4,
97 TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
98};
99
100enum tlm_gp_option
101{
102 TLM_MIN_PAYLOAD,
103 TLM_FULL_PAYLOAD,
104 TLM_FULL_PAYLOAD_ACCEPTED
105};
106
107#define TLM_BYTE_DISABLED 0x0
108#define TLM_BYTE_ENABLED 0xff
109
110//---------------------------------------------------------------------------
111// The generic payload class:
112//---------------------------------------------------------------------------
113
114extern template class tlm_array<tlm_extension_base *>;
115
116class tlm_generic_payload
117{
118 public:
119 tlm_generic_payload();
120 explicit tlm_generic_payload(tlm_mm_interface *mm);
121
122 void
123 acquire()
124 {
125 sc_assert(m_mm != 0);
126 m_ref_count++;
127 }
128
129 void
130 release()
131 {
132 sc_assert(m_mm != 0 && m_ref_count > 0);
133 if (--m_ref_count == 0)
134 m_mm->free(this);
135 }
136
137 int get_ref_count() const { return m_ref_count; }
138
139 void set_mm(tlm_mm_interface *mm) { m_mm = mm; }
140 bool has_mm() const { return m_mm != 0; }
141
142 void reset();
143
144 private:
145 // Disabled copy ctor and assignment operator.
146 tlm_generic_payload(const tlm_generic_payload &x);
147 tlm_generic_payload &operator = (const tlm_generic_payload &x);
148
149 public:
150 // Non-virtual deep-copying of the object.
151 void deep_copy_from(const tlm_generic_payload &other);
152
153 // To update the state of the original generic payload from a deep copy.
154 // Assumes that "other" was created from the original by calling
155 // deep_copy_from Argument use_byte_enable_on_read determines whether to
156 // use or ignores byte enables when copying back the data array on a read
157 // command.
158
159 void update_original_from(const tlm_generic_payload &other,
160 bool use_byte_enable_on_read=true);
161
162 void update_extensions_from(const tlm_generic_payload &other);
163
164 // Free all extensions. Useful when reusing a cloned transaction that
165 // doesn't have memory manager. Normal and sticky extensions are freed and
166 // extension array cleared.
167 void free_all_extensions();
168
169 virtual ~tlm_generic_payload();
170
171 //----------------
172 // API (including setters & getters).
173 //---------------
174
175 // Command related method.
176 bool is_read() const { return (m_command == TLM_READ_COMMAND); }
177 void set_read() { m_command = TLM_READ_COMMAND; }
178 bool is_write() const { return (m_command == TLM_WRITE_COMMAND); }
179 void set_write() { m_command = TLM_WRITE_COMMAND; }
180 tlm_command get_command() const { return m_command; }
181 void set_command(const tlm_command command) { m_command = command; }
182
183 // Address related methods.
184 sc_dt::uint64 get_address() const { return m_address; }
185 void set_address(const sc_dt::uint64 address) { m_address = address; }
186
187 // Data related methods.
188 unsigned char *get_data_ptr() const { return m_data; }
189 void set_data_ptr(unsigned char *data) { m_data = data; }
190
191 // Transaction length (in bytes) related methods.
192 unsigned int get_data_length() const { return m_length; }
193 void set_data_length(const unsigned int length) { m_length = length; }
194
195 // Response status related methods.
196 bool is_response_ok() const { return (m_response_status > 0); }
197 bool is_response_error() const { return (m_response_status <= 0); }
198 tlm_response_status
199 get_response_status() const
200 {
201 return m_response_status;
202 }
203 void
204 set_response_status(const tlm_response_status response_status)
205 {
206 m_response_status = response_status;
207 }
208 std::string get_response_string() const;
209
210 // Streaming related methods.
211 unsigned int get_streaming_width() const { return m_streaming_width; }
212 void
213 set_streaming_width(const unsigned int streaming_width)
214 {
215 m_streaming_width = streaming_width;
216 }
217
218 // Byte enable related methods.
219 unsigned char *get_byte_enable_ptr() const { return m_byte_enable; }
220 void
221 set_byte_enable_ptr(unsigned char *byte_enable)
222 {
223 m_byte_enable = byte_enable;
224 }
225 unsigned int
226 get_byte_enable_length() const
227 {
228 return m_byte_enable_length;
229 }
230 void
231 set_byte_enable_length(const unsigned int byte_enable_length)
232 {
233 m_byte_enable_length = byte_enable_length;
234 }
235
236 // This is the "DMI-hint" a slave can set this to true if it
237 // wants to indicate that a DMI request would be supported:
238 void
239 set_dmi_allowed(bool dmi_allowed)
240 {
241 m_dmi = dmi_allowed;
242 }
243 bool
244 is_dmi_allowed() const
245 {
246 return m_dmi;
247 }
248
249 // Use full set of attributes in DMI/debug?
250 tlm_gp_option get_gp_option() const { return m_gp_option; }
251 void set_gp_option(const tlm_gp_option gp_opt) { m_gp_option = gp_opt; }
252
253 private:
254 /* --------------------------------------------------------------------- */
255 /* Generic Payload attributes: */
256 /* --------------------------------------------------------------------- */
257 /* - m_command : Type of transaction. Three values supported: */
258 /* - TLM_WRITE_COMMAND */
259 /* - TLM_READ_COMMAND */
260 /* - TLM_IGNORE_COMMAND */
261 /* - m_address : Transaction base address (byte-addressing). */
262 /* - m_data : When m_command = TLM_WRITE_COMMAND contains a */
263 /* pointer to the data to be written in the target.*/
264 /* When m_command = TLM_READ_COMMAND contains a */
265 /* pointer where to copy the data read from the */
266 /* target. */
267 /* - m_length : Total number of bytes of the transaction. */
268 /* - m_response_status : This attribute indicates whether an error has */
269 /* occurred during the transaction. */
270 /* Values supported are: */
271 /* - TLM_OK_RESP */
272 /* - TLM_INCOMPLETE_RESP */
273 /* - TLM_GENERIC_ERROR_RESP */
274 /* - TLM_ADDRESS_ERROR_RESP */
275 /* - TLM_COMMAND_ERROR_RESP */
276 /* - TLM_BURST_ERROR_RESP */
277 /* - TLM_BYTE_ENABLE_ERROR_RESP */
278 /* */
279 /* - m_byte_enable : It can be used to create burst transfers where */
280 /* the address increment between each beat is greater */
281 /* than the word length of each beat, or to place */
282 /* words in selected byte lanes of a bus. */
283 /* - m_byte_enable_length : For a read or a write command, the target */
284 /* interpret the byte enable length attribute as the */
285 /* number of elements in the bytes enable array. */
286 /* - m_streaming_width : */
287 /* --------------------------------------------------------------------- */
288
289 sc_dt::uint64 m_address;
290 tlm_command m_command;
291 unsigned char *m_data;
292 unsigned int m_length;
293 tlm_response_status m_response_status;
294 bool m_dmi;
295 unsigned char *m_byte_enable;
296 unsigned int m_byte_enable_length;
297 unsigned int m_streaming_width;
298 tlm_gp_option m_gp_option;
299
300 public:
301 /* --------------------------------------------------------------------- */
302 /* Dynamic extension mechanism: */
303 /* --------------------------------------------------------------------- */
304 /* The extension mechanism is intended to enable initiator modules to */
305 /* optionally and transparently add data fields to the */
306 /* tlm_generic_payload. Target modules are free to check for extensions */
307 /* and may or may not react to the data in the extension fields. The */
308 /* definition of the extensions' semantics is solely in the */
309 /* responsibility of the user. */
310 /* */
311 /* The following rules apply: */
312 /* */
313 /* - Every extension class must be derived from tlm_extension, e.g.: */
314 /* class my_extension : public tlm_extension<my_extension> { ... } */
315 /* */
316 /* - A tlm_generic_payload object should be constructed after C++ */
317 /* static initialization time. This way it is guaranteed that the */
318 /* extension array is of sufficient size to hold all possible */
319 /* extensions. Alternatively, the initiator module can enforce a valid */
320 /* extension array size by calling the resize_extensions() method */
321 /* once before the first transaction with the payload object is */
322 /* initiated. */
323 /* */
324 /* - Initiators should use the the set_extension(e) or clear_extension(e)*/
325 /* methods for manipulating the extension array. The type of the */
326 /* argument must be a pointer to the specific registered extension */
327 /* type (my_extension in the above example) and is used to */
328 /* automatically locate the appropriate index in the array. */
329 /* */
330 /* - Targets can check for a specific extension by calling */
331 /* get_extension(e). e will point to zero if the extension is not */
332 /* present. */
333 /* */
334 /* --------------------------------------------------------------------- */
335
336 // Stick the pointer to an extension into the vector, return the
337 // previous value:
338 template <typename T>
339 T *
340 set_extension(T *ext)
341 {
342 return static_cast<T *>(set_extension(T::ID, ext));
343 }
344
345 // Non-templatized version with manual index:
346 tlm_extension_base *set_extension(
347 unsigned int index, tlm_extension_base *ext);
348
349 // Stick the pointer to an extension into the vector, return the
350 // previous value and schedule its release.
351 template <typename T>
352 T *
353 set_auto_extension(T *ext)
354 {
355 return static_cast<T *>(set_auto_extension(T::ID, ext));
356 }
357
358 // Non-templatized version with manual index:
359 tlm_extension_base *set_auto_extension(
360 unsigned int index, tlm_extension_base *ext);
361
362 // Check for an extension, ext will point to 0 if not present.
363 template <typename T>
364 void get_extension(T *& ext) const { ext = get_extension<T>(); }
365 template <typename T>
366 T *
367 get_extension() const
368 {
369 return static_cast<T*>(get_extension(T::ID));
370 }
371 // Non-templatized version with manual index:
372 tlm_extension_base *get_extension(unsigned int index) const;
373
374 // This call just removes the extension from the txn but does not
375 // call free() or tells the MM to do so it return false if there was
376 // active MM so you are now in an unsafe situation recommended use:
377 // when 100% sure there is no MM.
378 template <typename T>
379 void clear_extension(const T *ext) { clear_extension<T>(); }
380
381 // This call just removes the extension from the txn but does not
382 // call free() or tells the MM to do so it return false if there was
383 // active MM so you are now in an unsafe situation recommended use: when
384 // 100% sure there is no MM.
385 template <typename T>
386 void clear_extension() { clear_extension(T::ID); }
387
388 // This call removes the extension from the txn and does call free() or
389 // tells the MM to do so when the txn is finally done recommended use:
390 // when not sure there is no MM.
391 template <typename T>
392 void release_extension(T *ext)
393 {
394 release_extension<T>();
395 }
396
397 // This call removes the extension from the txn and does call free() or
398 // tells the MM to do so when the txn is finally done recommended use:
399 // when not sure there is no MM
400 template <typename T>
401 void release_extension()
402 {
403 release_extension(T::ID);
404 }
405
406 private:
407 // Non-templatized version with manual index
408 void clear_extension(unsigned int index);
409 // Non-templatized version with manual index
410 void release_extension(unsigned int index);
411
412 public:
413 // Make sure the extension array is large enough. Can be called once by
414 // an initiator module (before issuing the first transaction) to make
415 // sure that the extension array is of correct size. This is only needed
416 // if the initiator cannot guarantee that the generic payload object is
417 // allocated after C++ static construction time.
418 void resize_extensions();
419
420 private:
421 tlm_array<tlm_extension_base *> m_extensions;
422 tlm_mm_interface *m_mm;
423 unsigned int m_ref_count;
424};
425
426} // namespace tlm
427
428#endif /* __SYSTEMC_EXT_TLM_CORE_2_GENERIC_PAYLOAD_GP_HH__ */