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