00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __TLM_GP_H__
00020 #define __TLM_GP_H__
00021
00022 #include <systemc>
00023 #include "tlm_array.h"
00024
00025 namespace tlm {
00026
00027 class
00028 tlm_generic_payload;
00029
00030 class tlm_mm_interface {
00031 public:
00032 virtual void free(tlm_generic_payload*) = 0;
00033 virtual ‾tlm_mm_interface() {}
00034 };
00035
00036
00037
00038
00039
00040 inline unsigned int max_num_extensions(bool increment=false)
00041 {
00042 static unsigned int max_num = 0;
00043 if (increment) ++max_num;
00044 return max_num;
00045 }
00046
00047
00048
00049 class tlm_extension_base
00050 {
00051 public:
00052 virtual tlm_extension_base* clone() const = 0;
00053 virtual void free() { delete this; }
00054 virtual void copy_from(tlm_extension_base const &) = 0;
00055 protected:
00056 virtual ‾tlm_extension_base() {}
00057 static unsigned int register_extension()
00058 {
00059 return (max_num_extensions(true) - 1);
00060 };
00061 };
00062
00063
00064
00065
00066
00067
00068
00069 template <typename T>
00070 class tlm_extension : public tlm_extension_base
00071 {
00072 public:
00073 virtual tlm_extension_base* clone() const = 0;
00074 virtual void copy_from(tlm_extension_base const &ext) = 0;
00075 virtual ‾tlm_extension() {}
00076 const static unsigned int ID;
00077 };
00078
00079 template <typename T>
00080 const
00081 unsigned int tlm_extension<T>::ID = tlm_extension_base::register_extension();
00082
00083
00084
00085
00086 enum tlm_command {
00087 TLM_READ_COMMAND,
00088 TLM_WRITE_COMMAND,
00089 TLM_IGNORE_COMMAND
00090 };
00091
00092 enum tlm_response_status {
00093 TLM_OK_RESPONSE = 1,
00094 TLM_INCOMPLETE_RESPONSE = 0,
00095 TLM_GENERIC_ERROR_RESPONSE = -1,
00096 TLM_ADDRESS_ERROR_RESPONSE = -2,
00097 TLM_COMMAND_ERROR_RESPONSE = -3,
00098 TLM_BURST_ERROR_RESPONSE = -4,
00099 TLM_BYTE_ENABLE_ERROR_RESPONSE = -5
00100 };
00101
00102 #define TLM_BYTE_DISABLED 0x0
00103 #define TLM_BYTE_ENABLED 0xff
00104
00105
00106
00107
00108 class tlm_generic_payload {
00109
00110 public:
00111
00112
00113
00114
00115
00116 tlm_generic_payload()
00117 : m_address(0)
00118 , m_command(TLM_IGNORE_COMMAND)
00119 , m_data(0)
00120 , m_length(0)
00121 , m_response_status(TLM_INCOMPLETE_RESPONSE)
00122 , m_dmi(false)
00123 , m_byte_enable(0)
00124 , m_byte_enable_length(0)
00125 , m_streaming_width(0)
00126 , m_extensions(max_num_extensions())
00127 , m_mm(0)
00128 , m_ref_count(0)
00129 {
00130 }
00131
00132 explicit tlm_generic_payload(tlm_mm_interface* mm)
00133 : m_address(0)
00134 , m_command(TLM_IGNORE_COMMAND)
00135 , m_data(0)
00136 , m_length(0)
00137 , m_response_status(TLM_INCOMPLETE_RESPONSE)
00138 , m_dmi(false)
00139 , m_byte_enable(0)
00140 , m_byte_enable_length(0)
00141 , m_streaming_width(0)
00142 , m_extensions(max_num_extensions())
00143 , m_mm(mm)
00144 , m_ref_count(0)
00145 {
00146 }
00147
00148 void acquire(){assert(m_mm != 0); m_ref_count++;}
00149 void release(){assert(m_mm != 0); if (--m_ref_count==0) m_mm->free(this);}
00150 int get_ref_count(){return m_ref_count;}
00151 void set_mm(tlm_mm_interface* mm) { m_mm = mm; }
00152 bool has_mm() { return m_mm != 0; }
00153
00154 void reset(){
00155
00156 m_extensions.free_entire_cache();
00157 };
00158
00159
00160 private:
00161
00162
00163 tlm_generic_payload(const tlm_generic_payload& x)
00164 : m_address(x.get_address())
00165 , m_command(x.get_command())
00166 , m_data(x.get_data_ptr())
00167 , m_length(x.get_data_length())
00168 , m_response_status(x.get_response_status())
00169 , m_dmi(x.is_dmi_allowed())
00170 , m_byte_enable(x.get_byte_enable_ptr())
00171 , m_byte_enable_length(x.get_byte_enable_length())
00172 , m_streaming_width(x.get_streaming_width())
00173 , m_extensions(max_num_extensions())
00174 {
00175
00176 for(unsigned int i=0; i<m_extensions.size(); i++)
00177 {
00178 m_extensions[i] = x.get_extension(i);
00179 }
00180 }
00181
00182
00183 tlm_generic_payload& operator= (const tlm_generic_payload& x)
00184 {
00185 m_command = x.get_command();
00186 m_address = x.get_address();
00187 m_data = x.get_data_ptr();
00188 m_length = x.get_data_length();
00189 m_response_status = x.get_response_status();
00190 m_byte_enable = x.get_byte_enable_ptr();
00191 m_byte_enable_length = x.get_byte_enable_length();
00192 m_streaming_width = x.get_streaming_width();
00193 m_dmi = x.is_dmi_allowed();
00194
00195
00196
00197
00198
00199 for(unsigned int i=0; i<m_extensions.size(); i++)
00200 {
00201 m_extensions[i] = x.get_extension(i);
00202 }
00203 return (*this);
00204 }
00205 public:
00206
00207 void deep_copy_from(const tlm_generic_payload & other)
00208 {
00209 m_command = other.get_command();
00210 m_address = other.get_address();
00211 m_length = other.get_data_length();
00212 m_response_status = other.get_response_status();
00213 m_byte_enable_length = other.get_byte_enable_length();
00214 m_streaming_width = other.get_streaming_width();
00215 m_dmi = other.is_dmi_allowed();
00216
00217
00218
00219 if(m_data && other.m_data)
00220 {
00221 memcpy(m_data, other.m_data, m_length);
00222 }
00223
00224
00225 if(m_byte_enable && other.m_byte_enable)
00226 {
00227 memcpy(m_byte_enable, other.m_byte_enable, m_byte_enable_length);
00228 }
00229
00230 for(unsigned int i=0; i<other.m_extensions.size(); i++)
00231 {
00232 if(other.m_extensions[i])
00233 {
00234 if(!m_extensions[i])
00235 {
00236 tlm_extension_base *ext = other.m_extensions[i]->clone();
00237 if(ext)
00238 {
00239 if(has_mm())
00240 {
00241 set_auto_extension(i, ext);
00242 }
00243 else
00244 {
00245 set_extension(i, ext);
00246 }
00247 }
00248 }
00249 else
00250 {
00251 m_extensions[i]->copy_from(*other.m_extensions[i]);
00252 }
00253 }
00254 }
00255 }
00256
00257 void update_extensions_from(const tlm_generic_payload & other)
00258 {
00259
00260 for(unsigned int i=0; i<other.m_extensions.size(); i++)
00261 {
00262 if(other.m_extensions[i])
00263 {
00264 if(m_extensions[i])
00265 {
00266 m_extensions[i]->copy_from(*other.m_extensions[i]);
00267 }
00268 }
00269 }
00270 }
00271
00272
00273
00274 void free_all_extensions()
00275 {
00276 m_extensions.free_entire_cache();
00277 for(unsigned int i=0; i<m_extensions.size(); i++)
00278 {
00279 if(m_extensions[i])
00280 {
00281 m_extensions[i]->free();
00282 m_extensions[i] = 0;
00283 }
00284 }
00285 }
00286
00287
00288
00289 virtual ‾tlm_generic_payload() {
00290 for(unsigned int i=0; i<m_extensions.size(); i++)
00291 if(m_extensions[i]) m_extensions[i]->free();
00292 }
00293
00294
00295
00296
00297
00298
00299 bool is_read() const {return (m_command == TLM_READ_COMMAND);}
00300 void set_read() {m_command = TLM_READ_COMMAND;}
00301 bool is_write() const {return (m_command == TLM_WRITE_COMMAND);}
00302 void set_write() {m_command = TLM_WRITE_COMMAND;}
00303 tlm_command get_command() const {return m_command;}
00304 void set_command(const tlm_command command) {m_command = command;}
00305
00306
00307 sc_dt::uint64 get_address() const {return m_address;}
00308 void set_address(const sc_dt::uint64 address) {m_address = address;}
00309
00310
00311 unsigned char* get_data_ptr() const {return m_data;}
00312 void set_data_ptr(unsigned char* data) {m_data = data;}
00313
00314
00315 unsigned int get_data_length() const {return m_length;}
00316 void set_data_length(const unsigned int length) {m_length = length;}
00317
00318
00319 bool is_response_ok() const {return (m_response_status > 0);}
00320 bool is_response_error() const {return (m_response_status <= 0);}
00321 tlm_response_status get_response_status() const {return m_response_status;}
00322 void set_response_status(const tlm_response_status response_status)
00323 {m_response_status = response_status;}
00324 std::string get_response_string() const
00325 {
00326 switch(m_response_status)
00327 {
00328 case TLM_OK_RESPONSE: return "TLM_OK_RESPONSE";
00329 case TLM_INCOMPLETE_RESPONSE: return "TLM_INCOMPLETE_RESPONSE";
00330 case TLM_GENERIC_ERROR_RESPONSE: return "TLM_GENERIC_ERROR_RESPONSE";
00331 case TLM_ADDRESS_ERROR_RESPONSE: return "TLM_ADDRESS_ERROR_RESPONSE";
00332 case TLM_COMMAND_ERROR_RESPONSE: return "TLM_COMMAND_ERROR_RESPONSE";
00333 case TLM_BURST_ERROR_RESPONSE: return "TLM_BURST_ERROR_RESPONSE";
00334 case TLM_BYTE_ENABLE_ERROR_RESPONSE: return "TLM_BYTE_ENABLE_ERROR_RESPONSE";
00335 }
00336 return "TLM_UNKNOWN_RESPONSE";
00337 }
00338
00339
00340 unsigned int get_streaming_width() const {return m_streaming_width;}
00341 void set_streaming_width(const unsigned int streaming_width) {m_streaming_width = streaming_width; }
00342
00343
00344 unsigned char* get_byte_enable_ptr() const {return m_byte_enable;}
00345 void set_byte_enable_ptr(unsigned char* byte_enable){m_byte_enable = byte_enable;}
00346 unsigned int get_byte_enable_length() const {return m_byte_enable_length;}
00347 void set_byte_enable_length(const unsigned int byte_enable_length){m_byte_enable_length = byte_enable_length;}
00348
00349
00350
00351 void set_dmi_allowed(bool dmi_allowed) { m_dmi = dmi_allowed; }
00352 bool is_dmi_allowed() const { return m_dmi; }
00353
00354 private:
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 sc_dt::uint64 m_address;
00392 tlm_command m_command;
00393 unsigned char* m_data;
00394 unsigned int m_length;
00395 tlm_response_status m_response_status;
00396 bool m_dmi;
00397 unsigned char* m_byte_enable;
00398 unsigned int m_byte_enable_length;
00399 unsigned int m_streaming_width;
00400
00401 public:
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 template <typename T> T* set_extension(T* ext)
00441 {
00442 return static_cast<T*>(set_extension(T::ID, ext));
00443 }
00444
00445
00446 tlm_extension_base* set_extension(unsigned int index,
00447 tlm_extension_base* ext)
00448 {
00449 tlm_extension_base* tmp = m_extensions[index];
00450 m_extensions[index] = ext;
00451 return tmp;
00452 }
00453
00454
00455
00456 template <typename T> T* set_auto_extension(T* ext)
00457 {
00458 return static_cast<T*>(set_auto_extension(T::ID, ext));
00459 }
00460
00461
00462 tlm_extension_base* set_auto_extension(unsigned int index,
00463 tlm_extension_base* ext)
00464 {
00465 tlm_extension_base* tmp = m_extensions[index];
00466 m_extensions[index] = ext;
00467 if (!tmp) m_extensions.insert_in_cache(&m_extensions[index]);
00468 assert(m_mm != 0);
00469 return tmp;
00470 }
00471
00472
00473 template <typename T> void get_extension(T*& ext) const
00474 {
00475 ext = get_extension<T>();
00476 }
00477 template <typename T> T* get_extension() const
00478 {
00479 return static_cast<T*>(get_extension(T::ID));
00480 }
00481
00482 tlm_extension_base* get_extension(unsigned int index) const
00483 {
00484 return m_extensions[index];
00485 }
00486
00487
00488
00489
00490
00491 template <typename T> void clear_extension(const T* ext)
00492 {
00493 clear_extension<T>();
00494 }
00495
00496
00497
00498
00499
00500 template <typename T> void clear_extension()
00501 {
00502 clear_extension(T::ID);
00503 }
00504
00505
00506
00507
00508 template <typename T> void release_extension(T* ext)
00509 {
00510 release_extension<T>();
00511 }
00512
00513
00514
00515
00516 template <typename T> void release_extension()
00517 {
00518 release_extension(T::ID);
00519 }
00520
00521 private:
00522
00523 void clear_extension(unsigned int index)
00524 {
00525 m_extensions[index] = static_cast<tlm_extension_base*>(0);
00526 }
00527
00528 void release_extension(unsigned int index)
00529 {
00530 if (m_mm)
00531 {
00532 m_extensions.insert_in_cache(&m_extensions[index]);
00533 }
00534 else
00535 {
00536 m_extensions[index]->free();
00537 m_extensions[index] = static_cast<tlm_extension_base*>(0);
00538 }
00539 }
00540
00541 public:
00542
00543
00544
00545
00546
00547 void resize_extensions()
00548 {
00549 m_extensions.expand(max_num_extensions());
00550 }
00551
00552 private:
00553 tlm_array<tlm_extension_base*> m_extensions;
00554 tlm_mm_interface* m_mm;
00555 unsigned int m_ref_count;
00556 };
00557
00558 }
00559
00560 #endif