19 #ifndef __TLM_ENDIAN_CONV_H__
20 #define __TLM_ENDIAN_CONV_H__
145 #define uchar unsigned char
147 #define TLM_END_CONV_DONT_UNDEF_UCHAR
154 class tlm_endian_context;
266 for(ptrdiff_t i=0; i!=
sizeof(D); i++) tmp[i] = c;
272 operator bool()
const {
return b;}
277 template<
class D> D tlm_bool<D>::TLM_TRUE
279 template<
class D> D tlm_bool<D>::TLM_FALSE
312 int orig_stream_width,
int sizeof_databus,
316 for(
int orig_sword = 0, new_sword = 0; new_sword < new_len;
317 new_sword += new_stream_width, orig_sword += orig_stream_width) {
320 for(
int orig_dword = orig_sword;
321 orig_dword < orig_sword + orig_stream_width; orig_dword +=
sizeof(D)) {
323 for(
int curr_byte = orig_dword +
sizeof(D) - 1;
324 curr_byte >= orig_dword; curr_byte--) {
326 ptrdiff_t he_index = ((ie_addr++) ^ (sizeof_databus - 1))
327 - new_start_address + new_sword;
328 COPY(ie_data+curr_byte,
329 ie_be+(curr_byte % be_length),
330 he_data+he_index, he_be+he_index);
339 template<
class DATAWORD>
inline void
353 template<
class DATAWORD>
inline void
356 tc->
from_f = &(tlm_from_hostendian_generic<DATAWORD>);
362 if(s_width >= length) s_width = length;
363 int nr_stream_words = length/s_width;
368 & ~(sizeof_databus - 1));
370 int new_stream_width = end_address - new_address + sizeof_databus;
371 int new_length = new_stream_width * nr_stream_words;
395 loop_generic0<DATAWORD, ©_dbtrue0>(new_length,
396 new_stream_width, s_width, sizeof_databus, tc->
address,
400 loop_generic0<DATAWORD, ©_db0>(new_length,
401 new_stream_width, s_width, sizeof_databus, tc->
address,
407 loop_generic0<DATAWORD, ©_btrue0>(new_length,
408 new_stream_width, s_width, sizeof_databus, tc->
address,
412 loop_generic0<DATAWORD, ©_b0>(new_length,
413 new_stream_width, s_width, sizeof_databus, tc->
address,
426 *((D *)dest1) = *((D *)src1);
432 *((D *)dest1) = *((D *)src1);
433 *((D *)dest2) = *((D *)src2);
443 *((D *)dest2) = *((D *)src2);
453 *((D *)src1) = *((D *)dest1);
466 void FILLFALSE(
uchar *dest1),
void FILLFALSEuchar(
uchar *dest1)>
468 int bytes_left,
int len0,
int lenN,
int sizeof_databus,
470 ptrdiff_t d2b_src = bsrc - src;
471 ptrdiff_t d2b_dest = bdest - dest;
472 uchar *original_dest = dest;
476 if((src >= start) && (src < end)) {
477 for(
int i=0; i<len0; i++) {
478 COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
483 if(bytes_left <= 0)
return int(dest - original_dest);
485 for(
int i=0; i<len0; i++) {
486 FILLFALSEuchar(dest+d2b_dest);
491 src -= 2 *
sizeof(D);
494 for(
unsigned int i=1; i<sizeof_databus/
sizeof(D); i++) {
495 if((src >= start) && (src < end)) {
496 COPY(src, src+d2b_src, dest, dest+d2b_dest);
497 bytes_left -=
sizeof(D);
499 FILLFALSE(dest+d2b_dest);
502 if(bytes_left <= 0)
return int(dest - original_dest);
507 if((src >= start) && (src < end)) {
508 for(
int i=0; i<lenN; i++) {
509 COPYuchar(src, src+d2b_src, dest, dest+d2b_dest);
514 if(bytes_left <= 0)
return int(dest - original_dest);
516 for(
int i=0; i<lenN; i++) {
517 FILLFALSEuchar(dest+d2b_dest);
522 src += 2 * sizeof_databus;
529 template<
class DATAWORD>
inline void
534 int d_mask =
sizeof(DATAWORD) - 1;
535 int a_offset =
static_cast<int>(tc->
address & b_mask);
536 int len0 = (sizeof_databus - a_offset) & d_mask;
537 int lenN =
sizeof(DATAWORD) - len0;
540 uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start;
544 loop_word1<DATAWORD, ©_dbytrue1<DATAWORD>,
545 ©_dbytrue1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
546 tc->
length, len0, lenN, sizeof_databus, d_start, d_end, d,
549 loop_word1<DATAWORD, ©_dbyb1<DATAWORD>,
550 ©_dbyb1<uchar>, &no_b1<DATAWORD>, &no_b1<uchar> >(
551 tc->
length, len0, lenN, sizeof_databus, d_start, d_end, d,
560 template<
class DATAWORD>
inline void
563 tc->
from_f = &(tlm_from_hostendian_word<DATAWORD>);
567 int d_mask =
sizeof(DATAWORD) - 1;
569 int a_offset =
static_cast<int>(txn->
get_address() & b_mask);
570 int len0 = (sizeof_databus - a_offset) & d_mask;
571 int lenN =
sizeof(DATAWORD) - len0;
574 uchar *d = ptrdiff_t(((sizeof_databus - a_offset) & ~d_mask) + lenN) + d_start;
591 &true_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
593 d_start, d_end, d, 0, new_data, new_be));
597 ©_b1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
606 ©_d1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
608 d_start, d_end, d, 0, new_data, new_be));
612 ©_db1<uchar>, &false_b1<DATAWORD>, &false_b1<uchar> >(
628 template<
class D>
inline void copy_d2(D *src1, D *src2, D *dest1, D *dest2) {
632 template<
class D>
inline void copy_db2(D *src1, D *src2, D *dest1, D *dest2) {
638 inline void copy_dbyb2(D *src1, D *src2, D *dest1, D *dest2) {
642 template<
class D,
void COPY(D *src1, D *src2, D *dest1, D *dest2)>
644 int words,
int words_per_bus) {
645 ptrdiff_t src1to2 = (
char *)src2 - (
char *)src1;
646 ptrdiff_t dest1to2 = (
char *)dest2 - (
char *)dest1;
648 D *done = src1 + ptrdiff_t(words);
650 src1 += ptrdiff_t(words_per_bus - 1);
653 COPY(src1, (D *)(src1to2+(
char *)src1), dest1, (D *)(dest1to2+(
char *)dest1));
655 if((--src1) < bus_start) {
656 bus_start += ptrdiff_t(words_per_bus);
657 if(bus_start == done)
break;
658 src1 = bus_start + ptrdiff_t(words_per_bus - 1);
666 template<
class DATAWORD>
inline void
668 int words_per_bus = sizeof_databus/
sizeof(DATAWORD);
669 if(words_per_bus == 1)
return;
677 loop_aligned2<DATAWORD, ©_d2<DATAWORD> >(
679 0, (DATAWORD *)(tc->
data_ptr), 0, words, words_per_bus);
685 loop_aligned2<DATAWORD, ©_dbyb2<DATAWORD> >(
688 (DATAWORD *)(tc->
data_ptr), 0, words, words_per_bus);
696 template<
class DATAWORD>
inline void
699 tc->
from_f = &(tlm_from_hostendian_aligned<DATAWORD>);
702 int words_per_bus = sizeof_databus/
sizeof(DATAWORD);
703 if(words_per_bus == 1)
return;
707 DATAWORD *original_data = (DATAWORD *)(txn->
get_data_ptr());
713 if(original_be == 0) {
717 loop_aligned2<DATAWORD, ©_d2<DATAWORD> >(original_data, 0,
719 words, words_per_bus);
733 loop_aligned2<DATAWORD, ©_db2<DATAWORD> >(original_data, original_be,
740 loop_aligned2<DATAWORD, ©_d2<DATAWORD> >(original_be, 0,
742 words, words_per_bus);
751 template<
class DATAWORD>
inline void
759 template<
class DATAWORD>
inline void
762 tc->
from_f = &(tlm_from_hostendian_single<DATAWORD>);
769 (sizeof_databus - (a & mask) -
sizeof(DATAWORD)));
782 #ifndef TLM_END_CONV_DONT_UNDEF_UCHAR
789 #endif // multiple-inclusion protection
void copy_d2(D *src1, D *src2, D *dest1, D *dest2)
void copy_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void tlm_to_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus)
void loop_generic0(int new_len, int new_stream_width, int orig_stream_width, int sizeof_databus, sc_dt::uint64 orig_start_address, sc_dt::uint64 new_start_address, int be_length, uchar *ie_data, uchar *ie_be, uchar *he_data, uchar *he_be)
void copy_dbyb2(D *src1, D *src2, D *dest1, D *dest2)
unsigned int get_data_length() const
void copy_db0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void set_byte_enable_length(const unsigned int byte_enable_length)
void copy_d1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void tlm_to_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus)
tlm_endian_context * pop()
~tlm_endian_context_pool()
tlm_endian_context * next
void tlm_from_hostendian_aligned(tlm_generic_payload *txn, unsigned int sizeof_databus)
void set_byte_enable_ptr(unsigned char *byte_enable)
void copy_btrue0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
unsigned int get_byte_enable_length() const
void set_streaming_width(const unsigned int streaming_width)
void loop_aligned2(D *src1, D *src2, D *dest1, D *dest2, int words, int words_per_bus)
void copy_db2(D *src1, D *src2, D *dest1, D *dest2)
void tlm_to_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus)
tlm_endian_context_pool()
void get_extension(T *&ext) const
void tlm_from_hostendian_single(tlm_generic_payload *txn, unsigned int sizeof_databus)
void copy_db1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
tlm_extension_base * clone() const
T * set_extension(T *ext)
void copy_dbyb1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void push(tlm_endian_context *c)
void tlm_to_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus)
void(* from_f)(tlm_generic_payload *txn, unsigned int sizeof_databus)
tlm_endian_context * establish_context(tlm_generic_payload *txn)
void copy_dbyb0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void copy_dbtrue0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void tlm_from_hostendian(tlm_generic_payload *txn)
unsigned char * get_byte_enable_ptr() const
void tlm_from_hostendian_word(tlm_generic_payload *txn, unsigned int sizeof_databus)
void establish_dbuf(int len)
void set_data_length(const unsigned int length)
void false_b1(uchar *dest1)
void set_address(const sc_dt::uint64 address)
unsigned char * get_data_ptr() const
unsigned int get_streaming_width() const
void copy_b0(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
void tlm_from_hostendian_generic(tlm_generic_payload *txn, unsigned int sizeof_databus)
void copy_dbytrue1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
tlm_endian_context * first
void true_b1(uchar *src1, uchar *src2, uchar *dest1, uchar *dest2)
sc_dt::uint64 new_address
#define TLM_BYTE_DISABLED
static D make_uchar_array(uchar c)
void establish_bebuf(int len)
static tlm_endian_context_pool global_tlm_endian_context_pool
void set_data_ptr(unsigned char *data)
void copy_from(tlm_extension_base const &)
sc_dt::uint64 get_address() const
int loop_word1(int bytes_left, int len0, int lenN, int sizeof_databus, uchar *start, uchar *end, uchar *src, uchar *bsrc, uchar *dest, uchar *bdest)