diff --git a/lib/include/srslte/phy/common/sequence.h b/lib/include/srslte/phy/common/sequence.h index f01bc6513..aa3ed9b71 100644 --- a/lib/include/srslte/phy/common/sequence.h +++ b/lib/include/srslte/phy/common/sequence.h @@ -62,6 +62,8 @@ SRSLTE_API void srslte_sequence_apply_c(const int8_t* in, int8_t* out, uint32_t SRSLTE_API void srslte_sequence_apply_bit(const uint8_t* in, uint8_t* out, uint32_t length, uint32_t seed); +SRSLTE_API void srslte_sequence_apply_bit_packed(const uint8_t* in, uint8_t* out, uint32_t length, uint32_t seed); + SRSLTE_API int srslte_sequence_pbch(srslte_sequence_t* seq, srslte_cp_t cp, uint32_t cell_id); SRSLTE_API int srslte_sequence_pcfich(srslte_sequence_t* seq, uint32_t nslot, uint32_t cell_id); diff --git a/lib/src/phy/common/sequence.c b/lib/src/phy/common/sequence.c index 49dfd2f3c..13fc32ca3 100644 --- a/lib/src/phy/common/sequence.c +++ b/lib/src/phy/common/sequence.c @@ -657,4 +657,65 @@ void srslte_sequence_apply_bit(const uint8_t* in, uint8_t* out, uint32_t length, x1 = sequence_gen_LTE_pr_memless_step_x1(x1); x2 = sequence_gen_LTE_pr_memless_step_x2(x2); } -} \ No newline at end of file +} + +void srslte_sequence_apply_bit_packed(const uint8_t* in, uint8_t* out, uint32_t length, uint32_t seed) +{ + uint32_t x1 = sequence_x1_init; // X1 initial state is fix + uint32_t x2 = sequence_get_x2_init(seed); // loads x2 initial state + + uint64_t buffer = 0; + uint32_t count = 0; + + const uint8_t reverse_lut[256] = { + 0b00000000, 0b10000000, 0b01000000, 0b11000000, 0b00100000, 0b10100000, 0b01100000, 0b11100000, 0b00010000, + 0b10010000, 0b01010000, 0b11010000, 0b00110000, 0b10110000, 0b01110000, 0b11110000, 0b00001000, 0b10001000, + 0b01001000, 0b11001000, 0b00101000, 0b10101000, 0b01101000, 0b11101000, 0b00011000, 0b10011000, 0b01011000, + 0b11011000, 0b00111000, 0b10111000, 0b01111000, 0b11111000, 0b00000100, 0b10000100, 0b01000100, 0b11000100, + 0b00100100, 0b10100100, 0b01100100, 0b11100100, 0b00010100, 0b10010100, 0b01010100, 0b11010100, 0b00110100, + 0b10110100, 0b01110100, 0b11110100, 0b00001100, 0b10001100, 0b01001100, 0b11001100, 0b00101100, 0b10101100, + 0b01101100, 0b11101100, 0b00011100, 0b10011100, 0b01011100, 0b11011100, 0b00111100, 0b10111100, 0b01111100, + 0b11111100, 0b00000010, 0b10000010, 0b01000010, 0b11000010, 0b00100010, 0b10100010, 0b01100010, 0b11100010, + 0b00010010, 0b10010010, 0b01010010, 0b11010010, 0b00110010, 0b10110010, 0b01110010, 0b11110010, 0b00001010, + 0b10001010, 0b01001010, 0b11001010, 0b00101010, 0b10101010, 0b01101010, 0b11101010, 0b00011010, 0b10011010, + 0b01011010, 0b11011010, 0b00111010, 0b10111010, 0b01111010, 0b11111010, 0b00000110, 0b10000110, 0b01000110, + 0b11000110, 0b00100110, 0b10100110, 0b01100110, 0b11100110, 0b00010110, 0b10010110, 0b01010110, 0b11010110, + 0b00110110, 0b10110110, 0b01110110, 0b11110110, 0b00001110, 0b10001110, 0b01001110, 0b11001110, 0b00101110, + 0b10101110, 0b01101110, 0b11101110, 0b00011110, 0b10011110, 0b01011110, 0b11011110, 0b00111110, 0b10111110, + 0b01111110, 0b11111110, 0b00000001, 0b10000001, 0b01000001, 0b11000001, 0b00100001, 0b10100001, 0b01100001, + 0b11100001, 0b00010001, 0b10010001, 0b01010001, 0b11010001, 0b00110001, 0b10110001, 0b01110001, 0b11110001, + 0b00001001, 0b10001001, 0b01001001, 0b11001001, 0b00101001, 0b10101001, 0b01101001, 0b11101001, 0b00011001, + 0b10011001, 0b01011001, 0b11011001, 0b00111001, 0b10111001, 0b01111001, 0b11111001, 0b00000101, 0b10000101, + 0b01000101, 0b11000101, 0b00100101, 0b10100101, 0b01100101, 0b11100101, 0b00010101, 0b10010101, 0b01010101, + 0b11010101, 0b00110101, 0b10110101, 0b01110101, 0b11110101, 0b00001101, 0b10001101, 0b01001101, 0b11001101, + 0b00101101, 0b10101101, 0b01101101, 0b11101101, 0b00011101, 0b10011101, 0b01011101, 0b11011101, 0b00111101, + 0b10111101, 0b01111101, 0b11111101, 0b00000011, 0b10000011, 0b01000011, 0b11000011, 0b00100011, 0b10100011, + 0b01100011, 0b11100011, 0b00010011, 0b10010011, 0b01010011, 0b11010011, 0b00110011, 0b10110011, 0b01110011, + 0b11110011, 0b00001011, 0b10001011, 0b01001011, 0b11001011, 0b00101011, 0b10101011, 0b01101011, 0b11101011, + 0b00011011, 0b10011011, 0b01011011, 0b11011011, 0b00111011, 0b10111011, 0b01111011, 0b11111011, 0b00000111, + 0b10000111, 0b01000111, 0b11000111, 0b00100111, 0b10100111, 0b01100111, 0b11100111, 0b00010111, 0b10010111, + 0b01010111, 0b11010111, 0b00110111, 0b10110111, 0b01110111, 0b11110111, 0b00001111, 0b10001111, 0b01001111, + 0b11001111, 0b00101111, 0b10101111, 0b01101111, 0b11101111, 0b00011111, 0b10011111, 0b01011111, 0b11011111, + 0b00111111, 0b10111111, 0b01111111, 0b11111111, + }; + + for (uint32_t i = 0; i < length / 8; i++) { + // Generate sequence bits + while (count < 8) { + uint32_t c = (uint32_t)(x1 ^ x2); + buffer = buffer | ((SEQUENCE_MASK & c) << count); + + // Step sequences + x1 = sequence_gen_LTE_pr_memless_step_par_x1(x1); + x2 = sequence_gen_LTE_pr_memless_step_par_x2(x2); + + // Increase count + count += SEQUENCE_PAR_BITS; + } + + // Apply XOR + out[i] = in[i] ^ reverse_lut[buffer & 255UL]; + buffer = buffer >> 8UL; + count -= 8; + } +} diff --git a/lib/src/phy/common/test/sequence_test.c b/lib/src/phy/common/test/sequence_test.c index 5757118ab..2eae5d58a 100644 --- a/lib/src/phy/common/test/sequence_test.c +++ b/lib/src/phy/common/test/sequence_test.c @@ -10,10 +10,10 @@ * */ +#include "srslte/phy/common/sequence.h" +#include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/debug.h" -#include -#include -#include +#include "srslte/phy/utils/random.h" #define Nc 1600 #define MAX_SEQ_LEN (256 * 1024) @@ -24,6 +24,7 @@ static uint8_t c[Nc + MAX_SEQ_LEN + 31]; static float c_float[Nc + MAX_SEQ_LEN + 31]; static int16_t c_short[Nc + MAX_SEQ_LEN + 31]; static int8_t c_char[Nc + MAX_SEQ_LEN + 31]; +static uint8_t c_packed_gold[MAX_SEQ_LEN / 8]; static uint8_t c_packed[MAX_SEQ_LEN / 8]; static uint8_t c_unpacked[MAX_SEQ_LEN]; @@ -42,6 +43,7 @@ static int test_sequence(srslte_sequence_t* sequence, uint32_t seed, uint32_t le uint64_t interval_xor_short_us = 0; uint64_t interval_xor_char_us = 0; uint64_t interval_xor_unpacked_us = 0; + uint64_t interval_xor_packed_us = 0; gettimeofday(&t[1], NULL); @@ -72,7 +74,7 @@ static int test_sequence(srslte_sequence_t* sequence, uint32_t seed, uint32_t le c_char[n] = c[n] ? -1 : +1; } - srslte_bit_pack_vector(c, c_packed, length); + srslte_bit_pack_vector(c, c_packed_gold, length); if (memcmp(c, sequence->c, length) != 0) { ERROR("Unmatched c"); @@ -138,12 +140,26 @@ static int test_sequence(srslte_sequence_t* sequence, uint32_t seed, uint32_t le get_time_interval(t); interval_xor_unpacked_us = t->tv_sec * 1000000UL + t->tv_usec; + // Test in-place packed XOR + gettimeofday(&t[1], NULL); + for (uint32_t r = 0; r < repetitions; r++) { + srslte_sequence_apply_bit_packed(ones_packed, c_packed, length, seed); + } + gettimeofday(&t[2], NULL); + get_time_interval(t); + interval_xor_packed_us = t->tv_sec * 1000000UL + t->tv_usec; + if (memcmp(c_char, sequence->c_char, length * sizeof(int8_t)) != 0) { ERROR("Unmatched XOR c_char"); ret = SRSLTE_ERROR; } - if (memcmp(c_packed, sequence->c_bytes, length / 8) != 0) { + if (memcmp(c_packed_gold, sequence->c_bytes, length / 8) != 0) { + ERROR("Unmatched c_packed"); + ret = SRSLTE_ERROR; + } + + if (memcmp(c_packed_gold, c_packed, length / 8) != 0) { ERROR("Unmatched c_packed"); ret = SRSLTE_ERROR; } @@ -153,7 +169,7 @@ static int test_sequence(srslte_sequence_t* sequence, uint32_t seed, uint32_t le ret = SRSLTE_ERROR; } - printf("%08x; %8d; %8.1f; %8.1f; %8.1f; %8.1f; %8.1f; %8c\n", + printf("%08x; %8d; %8.1f; %8.1f; %8.1f; %8.1f; %8.1f; %8.1f; %8c\n", seed, length, (double)(length * repetitions) / (double)interval_gen_us, @@ -161,6 +177,7 @@ static int test_sequence(srslte_sequence_t* sequence, uint32_t seed, uint32_t le (double)(length * repetitions) / (double)interval_xor_short_us, (double)(length * repetitions) / (double)interval_xor_char_us, (double)(length * repetitions) / (double)interval_xor_unpacked_us, + (double)(length * repetitions) / (double)interval_xor_packed_us, ret == SRSLTE_SUCCESS ? 'y' : 'n'); return SRSLTE_SUCCESS; @@ -182,7 +199,7 @@ int main(int argc, char** argv) ones_char[i] = 1; ones_unpacked[i] = 0; if (i < MAX_SEQ_LEN / 8) { - ones_packed[i] = UINT8_MAX; + ones_packed[i] = 0; } } @@ -192,7 +209,7 @@ int main(int argc, char** argv) return SRSLTE_ERROR; } - printf("%8s; %8s; %8s; %8s; %8s; %8s; %8s; %8s;\n", + printf("%8s; %8s; %8s; %8s; %8s; %8s; %8s; %8s; %8s;\n", "seed", "length", "GEN", @@ -200,6 +217,7 @@ int main(int argc, char** argv) "XOR 16", "XOR 8", "XOR Unpack", + "XOR Pack", "Passed"); for (uint32_t length = min_length; length <= max_length; length = (length * 5) / 4) {