00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __TLM_ENDIAN_CONV_H__
00020 #define __TLM_ENDIAN_CONV_H__
00021
00022 #include <systemc>
00023 #include "tlm_gp.h"
00024
00025
00026 namespace tlm {
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 #ifndef uchar
00145 #define uchar unsigned char
00146 #else
00147 #define TLM_END_CONV_DONT_UNDEF_UCHAR
00148 #endif
00149
00150
00152
00153
00154 class tlm_endian_context;
00155 class tlm_endian_context_pool {
00156 public:
00157 tlm_endian_context *first;
00158 inline tlm_endian_context_pool();
00159 inline ~tlm_endian_context_pool();
00160 inline tlm_endian_context *pop();
00161 inline void push(tlm_endian_context *c);
00162 };
00163 static tlm_endian_context_pool global_tlm_endian_context_pool;
00164
00165
00166 class tlm_endian_context : public tlm_extension<tlm_endian_context> {
00167 public:
00168 tlm_endian_context() : dbuf_size(0), bebuf_size(0) {}
00169 ~tlm_endian_context() {
00170 if(dbuf_size > 0) delete [] new_dbuf;
00171 if(bebuf_size > 0) delete [] new_bebuf;
00172 }
00173
00174 sc_dt::uint64 address;
00175 sc_dt::uint64 new_address;
00176 uchar *data_ptr;
00177 uchar *byte_enable;
00178 int length;
00179 int stream_width;
00180
00181
00182 void (*from_f)(tlm_generic_payload *txn, unsigned int sizeof_databus);
00183 int sizeof_databus;
00184
00185
00186 uchar *new_dbuf, *new_bebuf;
00187 int dbuf_size, bebuf_size;
00188 void establish_dbuf(int len) {
00189 if(len <= dbuf_size) return;
00190 if(dbuf_size > 0) delete [] new_dbuf;
00191 new_dbuf = new uchar[len];
00192 dbuf_size = len;
00193 }
00194 void establish_bebuf(int len) {
00195 if(len <= bebuf_size) return;
00196 if(bebuf_size > 0) delete [] new_bebuf;
00197 new_bebuf = new uchar[len];
00198 bebuf_size = len;
00199 }
00200
00201
00202 void free() {
00203 global_tlm_endian_context_pool.push(this);
00204 }
00205 tlm_extension_base* clone() const {return 0;}
00206 void copy_from(tlm_extension_base const &) {return;}
00207
00208
00209 tlm_endian_context *next;
00210 };
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 inline tlm_endian_context *establish_context(tlm_generic_payload *txn) {
00227 tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
00228 if(tc == 0) {
00229 tc = global_tlm_endian_context_pool.pop();
00230 txn->set_extension(tc);
00231 }
00232 return tc;
00233 }
00234
00235 inline tlm_endian_context_pool::tlm_endian_context_pool() : first(0) {}
00236
00237 inline tlm_endian_context_pool::~tlm_endian_context_pool() {
00238 while(first != 0) {
00239 tlm_endian_context *next = first->next;
00240 delete first;
00241 first = next;
00242 }
00243 }
00244
00245 tlm_endian_context *tlm_endian_context_pool::pop() {
00246 if(first == 0) return new tlm_endian_context;
00247 tlm_endian_context *r = first;
00248 first = first->next;
00249 return r;
00250 }
00251
00252 void tlm_endian_context_pool::push(tlm_endian_context *c) {
00253 c->next = first;
00254 first = c;
00255 }
00256
00257
00258
00259 template<class D> class tlm_bool {
00260 public:
00261 static D TLM_TRUE;
00262 static D TLM_FALSE;
00263 static D make_uchar_array(uchar c) {
00264 D d;
00265 uchar *tmp = (uchar *)(&d);
00266 for(ptrdiff_t i=0; i!=sizeof(D); i++) tmp[i] = c;
00267 return d;
00268 }
00269
00270
00271 tlm_bool(D &d) : b(*((uchar*)&d) != TLM_BYTE_DISABLED) {}
00272 operator bool() const {return b;}
00273 private:
00274 bool b;
00275 };
00276
00277 template<class D> D tlm_bool<D>::TLM_TRUE
00278 = tlm_bool<D>::make_uchar_array(TLM_BYTE_ENABLED);
00279 template<class D> D tlm_bool<D>::TLM_FALSE
00280 = tlm_bool<D>::make_uchar_array(TLM_BYTE_DISABLED);
00281
00282
00283
00285
00286 inline void copy_db0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00287 *dest1 = *src1;
00288 *dest2 = *src2;
00289 }
00290
00291 inline void copy_dbtrue0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00292 *dest1 = *src1;
00293 *dest2 = TLM_BYTE_ENABLED;
00294 }
00295
00296 inline void copy_btrue0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00297 *dest2 = TLM_BYTE_ENABLED;
00298 }
00299
00300 inline void copy_b0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00301 *dest2 = *src2;
00302 }
00303
00304 inline void copy_dbyb0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00305 if(*dest2 == TLM_BYTE_ENABLED) *src1 = *dest1;
00306 }
00307
00308
00309 template<class D,
00310 void COPY(uchar *he_d, uchar *he_b, uchar *ie_d, uchar *ie_b)>
00311 inline void loop_generic0(int new_len, int new_stream_width,
00312 int orig_stream_width, int sizeof_databus,
00313 sc_dt::uint64 orig_start_address, sc_dt::uint64 new_start_address, int be_length,
00314 uchar *ie_data, uchar *ie_be, uchar *he_data, uchar *he_be) {
00315
00316 for(int orig_sword = 0, new_sword = 0; new_sword < new_len;
00317 new_sword += new_stream_width, orig_sword += orig_stream_width) {
00318
00319 sc_dt::uint64 ie_addr = orig_start_address;
00320 for(int orig_dword = orig_sword;
00321 orig_dword < orig_sword + orig_stream_width; orig_dword += sizeof(D)) {
00322
00323 for(int curr_byte = orig_dword + sizeof(D) - 1;
00324 curr_byte >= orig_dword; curr_byte--) {
00325
00326 ptrdiff_t he_index = ((ie_addr++) ^ (sizeof_databus - 1))
00327 - new_start_address + new_sword;
00328 COPY(ie_data+curr_byte,
00329 ie_be+(curr_byte % be_length),
00330 he_data+he_index, he_be+he_index);
00331 }
00332 }
00333 }
00334 }
00335
00336
00338
00339 template<class DATAWORD> inline void
00340 tlm_from_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00341 if(txn->is_read()) {
00342 tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
00343 loop_generic0<DATAWORD, ©_dbyb0>(txn->get_data_length(),
00344 txn->get_streaming_width(), tc->stream_width, sizeof_databus, tc->address,
00345 tc->new_address, txn->get_data_length(), tc->data_ptr, 0, txn->get_data_ptr(),
00346 txn->get_byte_enable_ptr());
00347 }
00348 }
00349
00350
00352
00353 template<class DATAWORD> inline void
00354 tlm_to_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00355 tlm_endian_context *tc = establish_context(txn);
00356 tc->from_f = &(tlm_from_hostendian_generic<DATAWORD>);
00357 tc->sizeof_databus = sizeof_databus;
00358
00359
00360 int s_width = txn->get_streaming_width();
00361 int length = txn->get_data_length();
00362 if(s_width >= length) s_width = length;
00363 int nr_stream_words = length/s_width;
00364
00365
00366 sc_dt::uint64 new_address = (txn->get_address() & ~(sizeof_databus - 1));
00367 sc_dt::uint64 end_address = ((txn->get_address() + s_width - 1)
00368 & ~(sizeof_databus - 1));
00369
00370 int new_stream_width = end_address - new_address + sizeof_databus;
00371 int new_length = new_stream_width * nr_stream_words;
00372
00373
00374 tc->data_ptr = txn->get_data_ptr();
00375 tc->address = txn->get_address();
00376 tc->new_address = new_address;
00377 tc->stream_width = s_width;
00378 uchar *orig_be = txn->get_byte_enable_ptr();
00379 int orig_be_length = txn->get_byte_enable_length();
00380
00381
00382 txn->set_address(new_address);
00383 tc->establish_dbuf(new_length);
00384 txn->set_data_ptr(tc->new_dbuf);
00385 tc->establish_bebuf(new_length);
00386 txn->set_byte_enable_ptr(tc->new_bebuf);
00387 memset(txn->get_byte_enable_ptr(), TLM_BYTE_DISABLED, new_length);
00388 txn->set_streaming_width(new_stream_width);
00389 txn->set_data_length(new_length);
00390 txn->set_byte_enable_length(new_length);
00391
00392
00393 if(txn->is_write()) {
00394 if(orig_be == 0) {
00395 loop_generic0<DATAWORD, ©_dbtrue0>(new_length,
00396 new_stream_width, s_width, sizeof_databus, tc->address,
00397 new_address, new_length, tc->data_ptr, 0, txn->get_data_ptr(),
00398 txn->get_byte_enable_ptr());
00399 } else {
00400 loop_generic0<DATAWORD, ©_db0>(new_length,
00401 new_stream_width, s_width, sizeof_databus, tc->address,
00402 new_address, orig_be_length, tc->data_ptr, orig_be, txn->get_data_ptr(),
00403 txn->get_byte_enable_ptr());
00404 }
00405 } else {
00406 if(orig_be == 0) {
00407 loop_generic0<DATAWORD, ©_btrue0>(new_length,
00408 new_stream_width, s_width, sizeof_databus, tc->address,
00409 new_address, new_length, tc->data_ptr, 0, txn->get_data_ptr(),
00410 txn->get_byte_enable_ptr());
00411 } else {
00412 loop_generic0<DATAWORD, ©_b0>(new_length,
00413 new_stream_width, s_width, sizeof_databus, tc->address,
00414 new_address, orig_be_length, tc->data_ptr, orig_be, txn->get_data_ptr(),
00415 txn->get_byte_enable_ptr());
00416 }
00417 }
00418 }
00419
00420
00421
00423
00424 template<class D>
00425 inline void copy_d1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00426 *((D *)dest1) = *((D *)src1);
00427 *((D *)dest2) = tlm_bool<D>::TLM_TRUE;
00428 }
00429
00430 template<class D>
00431 inline void copy_db1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00432 *((D *)dest1) = *((D *)src1);
00433 *((D *)dest2) = *((D *)src2);
00434 }
00435
00436 template<class D>
00437 inline void true_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00438 *((D *)dest2) = tlm_bool<D>::TLM_TRUE;
00439 }
00440
00441 template<class D>
00442 inline void copy_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00443 *((D *)dest2) = *((D *)src2);
00444 }
00445
00446 template<class D>
00447 inline void copy_dbyb1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00448 if(*src2 != TLM_BYTE_DISABLED) *((D *)src1) = *((D *)dest1);
00449 }
00450
00451 template<class D>
00452 inline void copy_dbytrue1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2) {
00453 *((D *)src1) = *((D *)dest1);
00454 }
00455
00456 template<class D> inline void false_b1(uchar *dest1) {
00457 *((D *)dest1) = tlm_bool<D>::TLM_FALSE;
00458 }
00459
00460 template<class D> inline void no_b1(uchar *dest1) {
00461 }
00462
00463 template<class D,
00464 void COPY(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2),
00465 void COPYuchar(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2),
00466 void FILLFALSE(uchar *dest1), void FILLFALSEuchar(uchar *dest1)>
00467 inline int loop_word1(
00468 int bytes_left, int len0, int lenN, int sizeof_databus,
00469 uchar *start, uchar *end, uchar *src, uchar *bsrc, uchar *dest, uchar *bdest) {
00470 ptrdiff_t d2b_src = bsrc - src;
00471 ptrdiff_t d2b_dest = bdest - dest;
00472 uchar *original_dest = dest;
00473
00474 while(true) {
00475
00476 if((src >= start) && (src < end)) {
00477 for(int i=0; i<len0; i++) {
00478 COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
00479 src++;
00480 dest++;
00481 }
00482 bytes_left -= len0;
00483 if(bytes_left <= 0) return int(dest - original_dest);
00484 } else {
00485 for(int i=0; i<len0; i++) {
00486 FILLFALSEuchar(dest+d2b_dest);
00487 src++;
00488 dest++;
00489 }
00490 }
00491 src -= 2 * sizeof(D);
00492
00493
00494 for(unsigned int i=1; i<sizeof_databus/sizeof(D); i++) {
00495 if((src >= start) && (src < end)) {
00496 COPY(src, src+d2b_src, dest, dest+d2b_dest);
00497 bytes_left -= sizeof(D);
00498 } else {
00499 FILLFALSE(dest+d2b_dest);
00500 }
00501 dest += sizeof(D);
00502 if(bytes_left <= 0) return int(dest - original_dest);
00503 src -= sizeof(D);
00504 }
00505
00506
00507 if((src >= start) && (src < end)) {
00508 for(int i=0; i<lenN; i++) {
00509 COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
00510 src++;
00511 dest++;
00512 }
00513 bytes_left -= lenN;
00514 if(bytes_left <= 0) return int(dest - original_dest);
00515 } else {
00516 for(int i=0; i<lenN; i++) {
00517 FILLFALSEuchar(dest+d2b_dest);
00518 src++;
00519 dest++;
00520 }
00521 }
00522 src += 2 * sizeof_databus;
00523 }
00524 }
00525
00526
00528
00529 template<class DATAWORD> inline void
00530 tlm_from_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00531 if(txn->is_read()) {
00532 tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
00533 sc_dt::uint64 b_mask = sizeof_databus - 1;
00534 int d_mask = sizeof(DATAWORD) - 1;
00535 int a_offset = static_cast<int>(tc->address & b_mask);
00536 int len0 = (sizeof_databus - a_offset) & d_mask;
00537 int lenN = sizeof(DATAWORD) - len0;
00538 uchar *d_start = tc->data_ptr;
00539 uchar *d_end = ptrdiff_t(tc->length) + d_start;
00540 uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start;
00541
00542
00543 if(tc->byte_enable == 0) {
00544 loop_word1<DATAWORD, ©_dbytrue1<DATAWORD>,
00545 ©_dbytrue1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
00546 tc->length, len0, lenN, sizeof_databus, d_start, d_end, d,
00547 0, txn->get_data_ptr(), 0);
00548 } else {
00549 loop_word1<DATAWORD, ©_dbyb1<DATAWORD>,
00550 ©_dbyb1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
00551 tc->length, len0, lenN, sizeof_databus, d_start, d_end, d,
00552 tc->byte_enable - d_start + d, txn->get_data_ptr(), 0);
00553 }
00554 }
00555 }
00556
00557
00559
00560 template<class DATAWORD> inline void
00561 tlm_to_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00562 tlm_endian_context *tc = establish_context(txn);
00563 tc->from_f = &(tlm_from_hostendian_word<DATAWORD>);
00564 tc->sizeof_databus = sizeof_databus;
00565
00566 sc_dt::uint64 b_mask = sizeof_databus - 1;
00567 int d_mask = sizeof(DATAWORD) - 1;
00568 sc_dt::uint64 a_aligned = txn->get_address() & ~b_mask;
00569 int a_offset = static_cast<int>(txn->get_address() & b_mask);
00570 int len0 = (sizeof_databus - a_offset) & d_mask;
00571 int lenN = sizeof(DATAWORD) - len0;
00572 uchar *d_start = txn->get_data_ptr();
00573 uchar *d_end = ptrdiff_t(txn->get_data_length()) + d_start;
00574 uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start;
00575
00576
00577 int long_enough = txn->get_data_length() + 2 * sizeof_databus;
00578 tc->establish_dbuf(long_enough);
00579 uchar *new_data = tc->new_dbuf;
00580 tc->establish_bebuf(long_enough);
00581 uchar *new_be = tc->new_bebuf;
00582
00583 if(txn->is_read()) {
00584 tc->data_ptr = d_start;
00585 tc->address = txn->get_address();
00586 tc->byte_enable = txn->get_byte_enable_ptr();
00587 tc->length = txn->get_data_length();
00588 if(txn->get_byte_enable_ptr() == 0) {
00589
00590 txn->set_data_length(loop_word1<DATAWORD, &true_b1<DATAWORD>,
00591 &true_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
00592 txn->get_data_length(), len0, lenN, sizeof_databus,
00593 d_start, d_end, d, 0, new_data, new_be));
00594 } else {
00595
00596 txn->set_data_length(loop_word1<DATAWORD, ©_b1<DATAWORD>,
00597 ©_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
00598 txn->get_data_length(), len0, lenN, sizeof_databus, d_start, d_end,
00599 d, txn->get_byte_enable_ptr() - d_start + d, new_data, new_be));
00600 }
00601 } else {
00602
00603 if(txn->get_byte_enable_ptr() == 0) {
00604
00605 txn->set_data_length(loop_word1<DATAWORD, ©_d1<DATAWORD>,
00606 ©_d1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
00607 txn->get_data_length(), len0, lenN, sizeof_databus,
00608 d_start, d_end, d, 0, new_data, new_be));
00609 } else {
00610
00611 txn->set_data_length(loop_word1<DATAWORD, ©_db1<DATAWORD>,
00612 ©_db1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
00613 txn->get_data_length(), len0, lenN, sizeof_databus, d_start, d_end,
00614 d, txn->get_byte_enable_ptr() - d_start + d, new_data, new_be));
00615 }
00616 }
00617 txn->set_byte_enable_length(txn->get_data_length());
00618 txn->set_streaming_width(txn->get_data_length());
00619 txn->set_data_ptr(new_data);
00620 txn->set_byte_enable_ptr(new_be);
00621 txn->set_address(a_aligned);
00622 }
00623
00624
00625
00627
00628 template<class D> inline void copy_d2(D *src1, D *src2, D *dest1, D *dest2) {
00629 *dest1 = *src1;
00630 }
00631
00632 template<class D> inline void copy_db2(D *src1, D *src2, D *dest1, D *dest2) {
00633 *dest1 = *src1;
00634 *dest2 = *src2;
00635 }
00636
00637 template<class D>
00638 inline void copy_dbyb2(D *src1, D *src2, D *dest1, D *dest2) {
00639 if(tlm_bool<D>(*src2)) *dest1 = *src1;
00640 }
00641
00642 template<class D, void COPY(D *src1, D *src2, D *dest1, D *dest2)>
00643 inline void loop_aligned2(D *src1, D *src2, D *dest1, D *dest2,
00644 int words, int words_per_bus) {
00645 ptrdiff_t src1to2 = (char *)src2 - (char *)src1;
00646 ptrdiff_t dest1to2 = (char *)dest2 - (char *)dest1;
00647
00648 D *done = src1 + ptrdiff_t(words);
00649 D *bus_start = src1;
00650 src1 += ptrdiff_t(words_per_bus - 1);
00651
00652 while(true) {
00653 COPY(src1, (D *)(src1to2+(char *)src1), dest1, (D *)(dest1to2+(char *)dest1));
00654 dest1++;
00655 if((--src1) < bus_start) {
00656 bus_start += ptrdiff_t(words_per_bus);
00657 if(bus_start == done) break;
00658 src1 = bus_start + ptrdiff_t(words_per_bus - 1);
00659 }
00660 }
00661 }
00662
00663
00665
00666 template<class DATAWORD> inline void
00667 tlm_from_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00668 int words_per_bus = sizeof_databus/sizeof(DATAWORD);
00669 if(words_per_bus == 1) return;
00670 int words = (txn->get_data_length())/sizeof(DATAWORD);
00671 tlm_endian_context *tc = txn->template get_extension<tlm_endian_context>();
00672
00673 if(txn->get_byte_enable_ptr() == 0) {
00674
00675 if(txn->is_read()) {
00676
00677 loop_aligned2<DATAWORD, ©_d2<DATAWORD> >(
00678 (DATAWORD *)(txn->get_data_ptr()),
00679 0, (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
00680 }
00681 } else {
00682
00683 if(txn->is_read()) {
00684
00685 loop_aligned2<DATAWORD, ©_dbyb2<DATAWORD> >(
00686 (DATAWORD *)(txn->get_data_ptr()),
00687 (DATAWORD *)(txn->get_byte_enable_ptr()),
00688 (DATAWORD *)(tc->data_ptr), 0, words, words_per_bus);
00689 }
00690 }
00691 }
00692
00693
00695
00696 template<class DATAWORD> inline void
00697 tlm_to_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00698 tlm_endian_context *tc = establish_context(txn);
00699 tc->from_f = &(tlm_from_hostendian_aligned<DATAWORD>);
00700 tc->sizeof_databus = sizeof_databus;
00701
00702 int words_per_bus = sizeof_databus/sizeof(DATAWORD);
00703 if(words_per_bus == 1) return;
00704 int words = (txn->get_data_length())/sizeof(DATAWORD);
00705
00706 DATAWORD *original_be = (DATAWORD *)(txn->get_byte_enable_ptr());
00707 DATAWORD *original_data = (DATAWORD *)(txn->get_data_ptr());
00708
00709
00710 tc->establish_dbuf(txn->get_data_length());
00711 txn->set_data_ptr(tc->new_dbuf);
00712
00713 if(original_be == 0) {
00714
00715 if(txn->is_write()) {
00716
00717 loop_aligned2<DATAWORD, ©_d2<DATAWORD> >(original_data, 0,
00718 (DATAWORD *)(txn->get_data_ptr()), 0,
00719 words, words_per_bus);
00720 } else {
00721
00722 tc->data_ptr = (uchar *)original_data;
00723 }
00724 } else {
00725
00726
00727 tc->establish_bebuf(txn->get_data_length());
00728 txn->set_byte_enable_ptr(tc->new_bebuf);
00729 txn->set_byte_enable_length(txn->get_data_length());
00730
00731 if(txn->is_write()) {
00732
00733 loop_aligned2<DATAWORD, ©_db2<DATAWORD> >(original_data, original_be,
00734 (DATAWORD *)(txn->get_data_ptr()),
00735 (DATAWORD *)(txn->get_byte_enable_ptr()), words, words_per_bus);
00736 } else {
00737
00738 tc->data_ptr = (uchar *)original_data;
00739
00740 loop_aligned2<DATAWORD, ©_d2<DATAWORD> >(original_be, 0,
00741 (DATAWORD *)(txn->get_byte_enable_ptr()), 0,
00742 words, words_per_bus);
00743 }
00744 }
00745 }
00746
00747
00748
00750
00751 template<class DATAWORD> inline void
00752 tlm_from_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00753
00754 }
00755
00756
00758
00759 template<class DATAWORD> inline void
00760 tlm_to_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus) {
00761 tlm_endian_context *tc = establish_context(txn);
00762 tc->from_f = &(tlm_from_hostendian_single<DATAWORD>);
00763 tc->sizeof_databus = sizeof_databus;
00764
00765
00766 sc_dt::uint64 mask = sizeof_databus-1;
00767 sc_dt::uint64 a = txn->get_address();
00768 txn->set_address((a & ~mask) |
00769 (sizeof_databus - (a & mask) - sizeof(DATAWORD)));
00770 }
00771
00772
00773
00775
00776 inline void tlm_from_hostendian(tlm_generic_payload *txn) {
00777 tlm_endian_context *tc = txn->get_extension<tlm_endian_context>();
00778 (*(tc->from_f))(txn, tc->sizeof_databus);
00779 }
00780
00781
00782 #ifndef TLM_END_CONV_DONT_UNDEF_UCHAR
00783 #undef uchar
00784 #endif
00785
00786 }
00787
00788
00789 #endif // multiple-inclusion protection
00790