Beispiel #1
0
int main(int argc, char **argv) {

  parse_args(argc, argv);
  
  srslte_tcod_gentable();

  srslte_tcod_t tcod;
  srslte_tcod_init(&tcod, 6144);

  uint32_t st=0, end=187;
  if (long_cb) {
    st=srslte_cbsegm_cbindex(long_cb);
    end=st;
  }
  
  for (uint32_t len=st;len<=end;len++) {
    long_cb = srslte_cbsegm_cbsize(len); 
    printf("Checking long_cb=%d\n", long_cb);
    for (int i=0;i<long_cb/8;i++) {
      input_bytes[i] = rand()%256;
    }
    
    srslte_bit_unpack_vector(input_bytes, input_bits, long_cb);

    if (SRSLTE_VERBOSE_ISINFO()) {
      printf("Input bits:\n");
      for (int i=0;i<long_cb/8;i++) {
        srslte_vec_fprint_b(stdout, &input_bits[i*8], 8);
      }
    }

    srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb);
    srslte_tcod_encode_lut(&tcod, input_bytes, parity, len);

    srslte_bit_unpack_vector(parity, parity_bits, 2*(long_cb+4));
    
    for (int i=0;i<long_cb;i++) {
      output_bits2[3*i] = input_bits[i];
      output_bits2[3*i+1] = parity_bits[i];
      output_bits2[3*i+2] = parity_bits[i+long_cb+4];
    }

    if (SRSLTE_VERBOSE_ISINFO()) {
      srslte_vec_fprint_b(stdout, output_bits2, 3*long_cb); 
      srslte_vec_fprint_b(stdout, output_bits, 3*long_cb);       
      printf("\n");
    }  
    for (int i=0;i<2*long_cb;i++) {
      if (output_bits2[long_cb+i] != output_bits[long_cb+i]) {
        printf("error in bit %d, len=%d\n", i, len);
        exit(-1);
      }
    }
  }
  
  srslte_tcod_free(&tcod);
  printf("Done\n");
  exit(0);
}
Beispiel #2
0
/**
 * Undoes rate matching for LTE Turbo Coder. Expands rate matched buffer to full size buffer.
 *
 * @param[in] input Input buffer of size in_len
 * @param[out] output Output buffer of size 3*srslte_cbsegm_cbsize(cb_idx)+12
 * @param[in] cb_idx Code block table index
 * @param[in] rv_idx Redundancy Version from DCI control message
 * @return Error code
 */
int srslte_rm_turbo_rx_lut_(int16_t *input, int16_t *output, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx, bool enable_input_tdec)
{

  if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {

#if SRSLTE_TDEC_EXPECT_INPUT_SB == 1
  int cb_len=srslte_cbsegm_cbsize(cb_idx);
  int idx = deinter_table_idx_from_sb_len(srslte_tdec_autoimp_get_subblocks(cb_len));
  uint16_t *deinter = NULL;
  if (idx < 0 || !enable_input_tdec) {
    deinter = deinterleaver[cb_idx][rv_idx];
  } else if (idx < NOF_DEINTER_TABLE_SB_IDX) {
    deinter = deinterleaver_sb[idx][cb_idx][rv_idx];
  } else {
    fprintf(stderr, "Sub-block size index %d not supported in srslte_rm_turbo_rx_lut()\n", idx);
    return -1;
  }
#else
  uint16_t *deinter = deinterleaver[cb_idx][rv_idx];
#endif

  #ifdef LV_HAVE_AVX
    return srslte_rm_turbo_rx_lut_avx(input, output, deinter, in_len, cb_idx, rv_idx);
  #else
  #ifdef LV_HAVE_SSE
    return srslte_rm_turbo_rx_lut_sse(input, output, deinter, in_len, cb_idx, rv_idx);
  #else
      uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;

      for (int i=0;i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
      return 0;    
  #endif
#endif
  } else {
    printf("Invalid inputs rv_idx=%d, cb_idx=%d\n", rv_idx, cb_idx);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Beispiel #3
0
void srslte_rm_turbo_gentables() {
  if (!rm_turbo_tables_generated) {
    rm_turbo_tables_generated = true; 
    for (int cb_idx=0;cb_idx<SRSLTE_NOF_TC_CB_SIZES;cb_idx++) {
      int cb_len = srslte_cbsegm_cbsize(cb_idx);
      int in_len = 3 * cb_len + 12;

      int nrows = (in_len / 3 - 1) / NCOLS + 1;
      int K_p = nrows * NCOLS;
      int ndummy = K_p - in_len / 3;
      if (ndummy < 0) {
        ndummy = 0;
      }

      for (int i = 0; i < 4; i++) {
        k0_vec[cb_idx][i][0] = nrows * (2 * (uint16_t) ceilf((float) (3 * K_p) / (float) (8 * nrows)) * i + 2);
        k0_vec[cb_idx][i][1] = -1;
      }
      srslte_rm_turbo_gentable_systematic(interleaver_systematic_bits[cb_idx], k0_vec[cb_idx], nrows, ndummy);
      srslte_bit_interleaver_init(&bit_interleavers_systematic_bits[cb_idx], interleaver_systematic_bits[cb_idx],
                                  (uint32_t) srslte_cbsegm_cbsize(cb_idx) + 4);

      srslte_rm_turbo_gentable_parity(interleaver_parity_bits[cb_idx], k0_vec[cb_idx], in_len / 3, nrows, ndummy);
      srslte_bit_interleaver_init(&bit_interleavers_parity_bits[cb_idx], interleaver_parity_bits[cb_idx],
                                  (uint32_t) (srslte_cbsegm_cbsize(cb_idx) + 4) * 2);

      for (int i = 0; i < 4; i++) {
        srslte_rm_turbo_gentable_receive(deinterleaver[cb_idx][i], in_len, i);

#if SRSLTE_TDEC_EXPECT_INPUT_SB == 1
        for (uint32_t s = 0; s < NOF_DEINTER_TABLE_SB_IDX; s++) {
          interleave_table_sb(deinterleaver[cb_idx][i], deinterleaver_sb[s][cb_idx][i], cb_idx,
                              deinter_table_sb_idx[s]);
        }
#endif
      }
    }
  }
}
Beispiel #4
0
int srslte_rm_turbo_rx_lut_8bit(int8_t *input, int8_t *output, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx)
{
  if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {

#if SRSLTE_TDEC_EXPECT_INPUT_SB == 1
    int cb_len=srslte_cbsegm_cbsize(cb_idx);
    int idx = deinter_table_idx_from_sb_len(srslte_tdec_autoimp_get_subblocks_8bit(cb_len));
    uint16_t *deinter = NULL;
    if (idx < 0) {
      deinter = deinterleaver[cb_idx][rv_idx];
    } else if (idx < NOF_DEINTER_TABLE_SB_IDX) {
      deinter = deinterleaver_sb[idx][cb_idx][rv_idx];
    } else {
      fprintf(stderr, "Sub-block size index %d not supported in srslte_rm_turbo_rx_lut()\n", idx);
      return -1;
    }
#else
    uint16_t *deinter = deinterleaver[cb_idx][rv_idx];
#endif

    // FIXME: AVX version of rm_turbo_rx_lut not working
    // Warning: Need to check if 8-bit sse version is correct

#ifdef LV_HAVE_SSE
    return srslte_rm_turbo_rx_lut_sse_8bit(input, output, deinter, in_len, cb_idx, rv_idx);
#else
    uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;

    for (int i=0;i<in_len;i++) {
      output[deinter[i%out_len]] += input[i];
    }
    return 0;
#endif
  } else {
    printf("Invalid inputs rv_idx=%d, cb_idx=%d\n", rv_idx, cb_idx);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Beispiel #5
0
/* Prepare output for sliding window decoder:
 * (0..long_cb-1) bits are systematic
 * (long_cb..2*long_cb-1) are parity0
 * (2*long_cb..3*long_cb-1) are parity1
 * then tail bits
 *
 * Within each block, bits are interleaved every nof_sb
 */
static void interleave_table_sb(uint16_t *in, uint16_t *out, uint32_t cb_idx, uint32_t nof_sb)
{
  int long_cb = srslte_cbsegm_cbsize(cb_idx);
  int out_len = 3*long_cb+12;
  for (int i=0;i<out_len;i++) {
    // Do not change tail bit order
    if (in[i] < 3*long_cb) {

      // align to 32 bytes (warning: must be same alignment as in rm_turbo.c)
      out[i] = (in[i]%3)*(long_cb+32)+inter(in[i]/3,nof_sb);
    } else {
      out[i] = (in[i]-3*long_cb)+3*(long_cb+32);
    }
  }
}
Beispiel #6
0
/**
 * Rate matching for LTE Turbo Coder
 *
 * @param[out] w_buff Preallocated softbuffer
 * @param[in] systematic Input code block in a byte array
 * @param[in] parity Input code turbo coder parity bits in a byte array
 * @param[out] output Rate matched output array of size out_len
 * @param out_len Output buffer size to be filled with as many FEC bits as fit
 * @param w_offset Start writing to output at this bit offset
 * @param cb_idx Code block index. Used to lookup interleaver parameters
 * @param rv_idx Redundancy Version Index. Indexed offset of FEC bits to copy
 *
 * @return Error code
 */
int srslte_rm_turbo_tx_lut(uint8_t *w_buff, uint8_t *systematic, uint8_t *parity, uint8_t *output, 
                           uint32_t cb_idx, uint32_t out_len, 
                           uint32_t w_offset, uint32_t rv_idx) 
{

  
  if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
    
    int in_len=3*srslte_cbsegm_cbsize(cb_idx)+12;
    
    
    /* Sub-block interleaver (5.1.4.1.1) and bit collection */
    if (rv_idx == 0) {
      
      // Systematic bits 
      //srslte_bit_interleave(systematic, w_buff, interleaver_systematic_bits[cb_idx], in_len/3);
      srslte_bit_interleaver_run(&bit_interleavers_systematic_bits[cb_idx], systematic, w_buff, 0);


      // Parity bits 
      //srslte_bit_interleave_w_offset(parity, &w_buff[in_len/24], interleaver_parity_bits[cb_idx], 2*in_len/3, 4);
      srslte_bit_interleaver_run(&bit_interleavers_parity_bits[cb_idx], parity, &w_buff[in_len/24], 4);
    }

    /* Bit selection and transmission 5.1.4.1.2 */    
    int w_len = 0; 
    int r_ptr = k0_vec[cb_idx][rv_idx][1]; 
    while (w_len < out_len) {
      int cp_len = out_len - w_len; 
      if (cp_len + r_ptr >= in_len) {
        cp_len = in_len - r_ptr;
      }
      srslte_bit_copy(output, w_len+w_offset, w_buff, r_ptr, cp_len);
      r_ptr += cp_len; 
      if (r_ptr >= in_len) {
        r_ptr -= in_len; 
      }
      w_len += cp_len; 
    }

    return 0;
  } else {
    return SRSLTE_ERROR_INVALID_INPUTS; 
  }
}
Beispiel #7
0
int main(int argc, char **argv) {

  parse_args(argc, argv);
  
  srslte_tcod_gentable();

  srslte_tcod_t tcod;
  srslte_tcod_init(&tcod, 6144);

  uint32_t st=0, end=187;
  if (long_cb) {
    st=srslte_cbsegm_cbindex(long_cb);
    end=st;
  }
  
  for (uint32_t len=st;len<=end;len++) {
    long_cb = srslte_cbsegm_cbsize(len); 
    printf("Checking long_cb=%d\n", long_cb);
    for (int i=0;i<long_cb/8;i++) {
      input_bytes[i] = rand()%256;
    }
    
    srslte_bit_unpack_vector(input_bytes, input_bits, long_cb);

    if (SRSLTE_VERBOSE_ISINFO()) {
      printf("Input bits:\n");
      for (int i=0;i<long_cb/8;i++) {
        srslte_vec_fprint_b(stdout, &input_bits[i*8], 8);
      }
    }

    srslte_tcod_encode(&tcod, input_bits, output_bits, long_cb);
    srslte_tcod_encode_lut(&tcod, input_bytes, output_bytes, long_cb);
    
    srslte_bit_unpack_vector(output_bytes, output_bits2, 2*long_cb+12);

    /* de-Interleace bits for comparison */
    for (int i=0;i<long_cb;i++) {
      for (int j=0;j<2;j++) {
        output_bits3[j*long_cb+i] = output_bits[3*i+j+1]; 
      }
    }
    // copy tail 
    memcpy(&output_bits3[2*long_cb], &output_bits[3*long_cb], 12);

    if (SRSLTE_VERBOSE_ISINFO()) {
      printf("1st encoder\n");
      srslte_vec_fprint_b(stdout, output_bits2, long_cb); 
      srslte_vec_fprint_b(stdout, output_bits3, long_cb); 
      
      printf("2nd encoder\n");
      srslte_vec_fprint_b(stdout, &output_bits2[long_cb], long_cb); 
      srslte_vec_fprint_b(stdout, &output_bits3[long_cb], long_cb); 

      printf("tail\n");
      srslte_vec_fprint_b(stdout, &output_bits2[2*long_cb], 12); 
      srslte_vec_fprint_b(stdout, &output_bits3[2*long_cb], 12); 
      printf("\n");
    }  
    for (int i=0;i<2*long_cb+12;i++) {
      if (output_bits2[i] != output_bits3[i]) {
        printf("error in bit %d, len=%d\n", i, len);
        exit(-1);
      }
    }
  }
  
  srslte_tcod_free(&tcod);
  printf("Done\n");
  exit(0);
}
Beispiel #8
0
/* Initializes the turbo decoder object */
int srslte_tdec_sse_init(srslte_tdec_sse_t * h, uint32_t max_long_cb)
{
  int ret = -1;
  bzero(h, sizeof(srslte_tdec_sse_t));
  uint32_t len = max_long_cb + SRSLTE_TCOD_TOTALTAIL;

  h->max_long_cb = max_long_cb;

  h->app1 = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->app1) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }
  h->app2 = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->app2) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }
  h->ext1 = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->ext1) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }
  h->ext2 = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->ext2) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }
  h->syst = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->syst) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }
  h->parity0 = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->parity0) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }
  h->parity1 = srslte_vec_malloc(sizeof(int16_t) * len);
  if (!h->parity1) {
    perror("srslte_vec_malloc");
    goto clean_and_exit;
  }

  if (map_gen_init(&h->dec, h->max_long_cb)) {
    goto clean_and_exit;
  }

  for (int i=0;i<SRSLTE_NOF_TC_CB_SIZES;i++) {
    if (srslte_tc_interl_init(&h->interleaver[i], srslte_cbsegm_cbsize(i)) < 0) {
      goto clean_and_exit;
    }
    srslte_tc_interl_LTE_gen(&h->interleaver[i], srslte_cbsegm_cbsize(i));
  }
  h->current_cbidx = -1; 
  ret = 0;
clean_and_exit:if (ret == -1) {
    srslte_tdec_sse_free(h);
  }
  return ret;
}
Beispiel #9
0
int srslte_rm_turbo_rx_lut_avx_8bit(int8_t *input, int8_t *output, uint16_t *deinter, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx)
{
  if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
    uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;

    const __m256i* xPtr   = (const __m256i*) input;
    const __m256i* lutPtr = (const __m256i*) deinter;
    __m256i xVal, lutVal1, lutVal2;

    int8_t x;
    uint16_t l;

    /* Simplify load if we do not need to wrap (ie high rates) */
    if (in_len <= out_len) {
      for (int i=0;i<in_len/32;i++) {
        xVal   = _mm256_loadu_si256(xPtr);
        xPtr ++;
        lutVal1 = _mm256_loadu_si256(lutPtr);
        lutPtr ++;
        lutVal2 = _mm256_loadu_si256(lutPtr);
        lutPtr ++;

        SAVE_OUTPUT8(0);
        SAVE_OUTPUT8(1);
        SAVE_OUTPUT8(2);
        SAVE_OUTPUT8(3);
        SAVE_OUTPUT8(4);
        SAVE_OUTPUT8(5);
        SAVE_OUTPUT8(6);
        SAVE_OUTPUT8(7);

        SAVE_OUTPUT8(8);
        SAVE_OUTPUT8(9);
        SAVE_OUTPUT8(10);
        SAVE_OUTPUT8(11);
        SAVE_OUTPUT8(12);
        SAVE_OUTPUT8(13);
        SAVE_OUTPUT8(14);
        SAVE_OUTPUT8(15);

        SAVE_OUTPUT8_2(0);
        SAVE_OUTPUT8_2(1);
        SAVE_OUTPUT8_2(2);
        SAVE_OUTPUT8_2(3);
        SAVE_OUTPUT8_2(4);
        SAVE_OUTPUT8_2(5);
        SAVE_OUTPUT8_2(6);
        SAVE_OUTPUT8_2(7);

        SAVE_OUTPUT8_2(8);
        SAVE_OUTPUT8_2(9);
        SAVE_OUTPUT8_2(10);
        SAVE_OUTPUT8_2(11);
        SAVE_OUTPUT8_2(12);
        SAVE_OUTPUT8_2(13);
        SAVE_OUTPUT8_2(14);
        SAVE_OUTPUT8_2(15);

      }
      for (int i=32*(in_len/32);i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
    } else {
      printf("wraps not implemented!\n");
#ifdef kk
      int intCnt = 32;
      int inputCnt = 0;
      int nwrapps = 0;
      while(inputCnt < in_len - 32) {
        xVal   = _mm256_loadu_si256(xPtr);
        xPtr ++;
        lutVal1 = _mm256_loadu_si256(lutPtr);
        lutPtr ++;
        lutVal2 = _mm256_loadu_si256(lutPtr);
        lutPtr ++;

        SAVE_OUTPUT8(0);
        SAVE_OUTPUT8(1);
        SAVE_OUTPUT8(2);
        SAVE_OUTPUT8(3);
        SAVE_OUTPUT8(4);
        SAVE_OUTPUT8(5);
        SAVE_OUTPUT8(6);
        SAVE_OUTPUT8(7);

        SAVE_OUTPUT8(8);
        SAVE_OUTPUT8(9);
        SAVE_OUTPUT8(10);
        SAVE_OUTPUT8(11);
        SAVE_OUTPUT8(12);
        SAVE_OUTPUT8(13);
        SAVE_OUTPUT8(14);
        SAVE_OUTPUT8(15);

        SAVE_OUTPUT8_2(0);
        SAVE_OUTPUT8_2(1);
        SAVE_OUTPUT8_2(2);
        SAVE_OUTPUT8_2(3);
        SAVE_OUTPUT8_2(4);
        SAVE_OUTPUT8_2(5);
        SAVE_OUTPUT8_2(6);
        SAVE_OUTPUT8_2(7);

        SAVE_OUTPUT8_2(8);
        SAVE_OUTPUT8_2(9);
        SAVE_OUTPUT8_2(10);
        SAVE_OUTPUT8_2(11);
        SAVE_OUTPUT8_2(12);
        SAVE_OUTPUT8_2(13);
        SAVE_OUTPUT8_2(14);
        SAVE_OUTPUT8_2(15);
        
        intCnt   += 32;
        inputCnt += 32;
        if (intCnt >= out_len && inputCnt < in_len - 32) {
          printf("warning rate matching wrapping remainder %d\n", out_len%32);
          /* Copy last elements */
          for (int j=(nwrapps+1)*out_len-(out_len%32) ;j<(nwrapps+1)*out_len;j++) {
            output[deinter[j%out_len]] += input[j];
            inputCnt++;
          }
          /* And wrap pointers */
          nwrapps++;
          intCnt = 32;
          xPtr   = (const __m256i*) &input[nwrapps*out_len];
          lutPtr = (const __m256i*) deinter;
        }
      }
      for (int i=inputCnt;i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
#endif
    }
    return 0;
  } else {
    printf("Invalid inputs rv_idx=%d, cb_idx=%d\n", rv_idx, cb_idx);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Beispiel #10
0
int srslte_rm_turbo_rx_lut_avx(int16_t *input, int16_t *output, uint16_t *deinter, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx)
{
  if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
    uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;

    const __m256i* xPtr   = (const __m256i*) input;
    const __m256i* lutPtr = (const __m256i*) deinter;
    __m256i xVal, lutVal;

    int16_t x;
    uint16_t l;

    /* Simplify load if we do not need to wrap (ie high rates) */
    if (in_len <= out_len) {
      for (int i=0;i<in_len/16;i++) {
        xVal   = _mm256_loadu_si256(xPtr);
        lutVal = _mm256_loadu_si256(lutPtr);
        SAVE_OUTPUT(0);
        SAVE_OUTPUT(1);
        SAVE_OUTPUT(2);
        SAVE_OUTPUT(3);
        SAVE_OUTPUT(4);
        SAVE_OUTPUT(5);
        SAVE_OUTPUT(6);
        SAVE_OUTPUT(7);

        SAVE_OUTPUT(8);
        SAVE_OUTPUT(9);
        SAVE_OUTPUT(10);
        SAVE_OUTPUT(11);
        SAVE_OUTPUT(12);
        SAVE_OUTPUT(13);
        SAVE_OUTPUT(14);
        SAVE_OUTPUT(15);

        xPtr ++;
        lutPtr ++;
      }
      for (int i=16*(in_len/16);i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
    } else {
      int intCnt = 16;
      int inputCnt = 0;
      int nwrapps = 0;
      while(inputCnt < in_len - 16) {
        xVal   = _mm256_loadu_si256(xPtr);
        lutVal = _mm256_loadu_si256(lutPtr);

        SAVE_OUTPUT(0);
        SAVE_OUTPUT(1);
        SAVE_OUTPUT(2);
        SAVE_OUTPUT(3);
        SAVE_OUTPUT(4);
        SAVE_OUTPUT(5);
        SAVE_OUTPUT(6);
        SAVE_OUTPUT(7);

        SAVE_OUTPUT(8);
        SAVE_OUTPUT(9);
        SAVE_OUTPUT(10);
        SAVE_OUTPUT(11);
        SAVE_OUTPUT(12);
        SAVE_OUTPUT(13);
        SAVE_OUTPUT(14);
        SAVE_OUTPUT(15);
        xPtr++;
        lutPtr++;
        intCnt   += 16;
        inputCnt += 16;
        if (intCnt >= out_len && inputCnt < in_len - 16) {
          /* Copy last elements */
          if ((out_len%16) == 12) {
            for (int j=(nwrapps+1)*out_len-12;j<(nwrapps+1)*out_len;j++) {
              output[deinter[j%out_len]] += input[j];
              inputCnt++;
            }
          } else {
            for (int j=(nwrapps+1)*out_len-4;j<(nwrapps+1)*out_len;j++) {
              output[deinter[j%out_len]] += input[j];
              inputCnt++;
            }
          }
          /* And wrap pointers */
          nwrapps++;
          intCnt = 16;
          xPtr   = (const __m256i*) &input[nwrapps*out_len];
          lutPtr = (const __m256i*) deinter;
        }
      }
      for (int i=inputCnt;i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
    }
    return 0;
  } else {
    printf("Invalid inputs rv_idx=%d, cb_idx=%d\n", rv_idx, cb_idx);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Beispiel #11
0
int srslte_rm_turbo_rx_lut_sse_8bit(int8_t *input, int8_t *output, uint16_t *deinter, uint32_t in_len, uint32_t cb_idx, uint32_t rv_idx)
{
  if (rv_idx < 4 && cb_idx < SRSLTE_NOF_TC_CB_SIZES) {
    uint32_t out_len = 3*srslte_cbsegm_cbsize(cb_idx)+12;

    const __m128i* xPtr   = (const __m128i*) input;
    const __m128i* lutPtr = (const __m128i*) deinter;
    __m128i xVal, lutVal1, lutVal2;

    /* Simplify load if we do not need to wrap (ie high rates) */
    if (in_len <= out_len) {
      for (int i=0;i<in_len/16;i++) {
        xVal   = _mm_loadu_si128(xPtr);
        xPtr ++;
        lutVal1 = _mm_loadu_si128(lutPtr);
        lutPtr++;
        lutVal2 = _mm_loadu_si128(lutPtr);
        lutPtr ++;

        for (int j=0;j<8;j++) {
          int8_t x  = (int8_t)  _mm_extract_epi8(xVal,   j);
          uint16_t l = (uint16_t) _mm_extract_epi16(lutVal1, j);
          output[l] += x;
        }
        for (int j=0;j<8;j++) {
          int8_t x  = (int8_t)  _mm_extract_epi8(xVal,   j+8);
          uint16_t l = (uint16_t) _mm_extract_epi16(lutVal2, j);
          output[l] += x;
        }
      }
      for (int i=16*(in_len/16);i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
    } else {
      int intCnt = 16;
      int inputCnt = 0;
      int nwrapps = 0;
      while(inputCnt < in_len - 16) {
        xVal   = _mm_loadu_si128(xPtr);
        xPtr ++;
        lutVal1 = _mm_loadu_si128(lutPtr);
        lutPtr++;
        lutVal2 = _mm_loadu_si128(lutPtr);
        lutPtr ++;

        for (int j=0;j<8;j++) {
          int8_t x  = (int8_t)  _mm_extract_epi8(xVal,   j);
          uint16_t l = (uint16_t) _mm_extract_epi16(lutVal1, j);
          output[l] += x;
        }
        for (int j=0;j<8;j++) {
          int8_t x  = (int8_t)  _mm_extract_epi8(xVal,   j+8);
          uint16_t l = (uint16_t) _mm_extract_epi16(lutVal2, j);
          output[l] += x;
        }
        intCnt   += 16;
        inputCnt += 16;
        if (intCnt >= out_len && inputCnt < in_len - 16) {
          /* Copy last elements */
          if ((out_len%16) == 12) {
            for (int j=(nwrapps+1)*out_len-12;j<(nwrapps+1)*out_len;j++) {
              output[deinter[j%out_len]] += input[j];
              inputCnt++;
            }
          } else {
            for (int j=(nwrapps+1)*out_len-4;j<(nwrapps+1)*out_len;j++) {
              output[deinter[j%out_len]] += input[j];
              inputCnt++;
            }
          }
          /* And wrap pointers */
          nwrapps++;
          intCnt = 16;
          xPtr   = (const __m128i*) &input[nwrapps*out_len];
          lutPtr = (const __m128i*) deinter;
        }
      }
      for (int i=inputCnt;i<in_len;i++) {
        output[deinter[i%out_len]] += input[i];
      }
    }


    return 0;
  } else {
    printf("Invalid inputs rv_idx=%d, cb_idx=%d\n", rv_idx, cb_idx);
    return SRSLTE_ERROR_INVALID_INPUTS;
  }
}
Beispiel #12
0
int main(int argc, char **argv) {
  int i;
  uint8_t *rm_bits, *rm_bits2, *rm_bits2_bytes;
  short *rm_bits_s; 
  float *rm_bits_f; 
  
  parse_args(argc, argv);
  
  srslte_rm_turbo_gentables();

  rm_bits_s = srslte_vec_malloc(sizeof(short) * nof_e_bits);
  if (!rm_bits_s) {
    perror("malloc");
    exit(-1);
  }
  rm_bits_f = srslte_vec_malloc(sizeof(float) * nof_e_bits);
  if (!rm_bits_f) {
    perror("malloc");
    exit(-1);
  }
  rm_bits = srslte_vec_malloc(sizeof(uint8_t) * nof_e_bits);
  if (!rm_bits) {
    perror("malloc");
    exit(-1);
  }
  rm_bits2 = malloc(sizeof(uint8_t) * nof_e_bits);
  if (!rm_bits2) {
    perror("malloc");
    exit(-1);
  }
  rm_bits2_bytes = malloc(sizeof(uint8_t) * nof_e_bits/8 + 1);
  if (!rm_bits2_bytes) {
    perror("malloc");
    exit(-1);
  }

  uint32_t st=0, end=188;
  if (cb_idx != -1) {
    st=cb_idx;
    end=cb_idx+1;
  }
  uint32_t rv_st=0, rv_end=4;
  if (rv_idx != -1) {
    rv_st=rv_idx;
    rv_end=rv_idx+1;
  }
  
  for (cb_idx=st;cb_idx<end;cb_idx++) {
    for (rv_idx=rv_st;rv_idx<rv_end;rv_idx++) {
      uint32_t long_cb_enc = 3*srslte_cbsegm_cbsize(cb_idx)+12;
      
      printf("checking cb_idx=%3d rv_idx=%d...", cb_idx, rv_idx);
      
      for (i = 0; i < long_cb_enc; i++) {
        bits[i] = rand() % 2;
      }
      
      bzero(buff_b, BUFFSZ * sizeof(uint8_t));
      
      srslte_rm_turbo_tx(buff_b, BUFFSZ, bits, long_cb_enc, rm_bits, nof_e_bits, 0);

      if (rv_idx > 0) {
        srslte_rm_turbo_tx(buff_b, BUFFSZ, bits, long_cb_enc, rm_bits, nof_e_bits, rv_idx);
      }

      for (int i=0;i<long_cb_enc/3;i++) {
        systematic[i] = bits[3*i];
        parity[i] = bits[3*i+1];
        parity[i+long_cb_enc/3] = bits[3*i+2];
      }
      
      srslte_bit_pack_vector(systematic, systematic_bytes, long_cb_enc/3);
      srslte_bit_pack_vector(parity, parity_bytes, 2*long_cb_enc/3);
      
      bzero(buff_b, BUFFSZ * sizeof(uint8_t));

      bzero(rm_bits2_bytes, nof_e_bits/8);
      srslte_rm_turbo_tx_lut(buff_b, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_e_bits, 0, 0);
      if (rv_idx > 0) {
        bzero(rm_bits2_bytes, nof_e_bits/8);
        srslte_rm_turbo_tx_lut(buff_b, systematic_bytes, parity_bytes, rm_bits2_bytes, cb_idx, nof_e_bits, 0, rv_idx);
      }

      srslte_bit_unpack_vector(rm_bits2_bytes, rm_bits2, nof_e_bits);

      for (int i=0;i<nof_e_bits;i++) {
        if (rm_bits2[i] != rm_bits[i]) {
          printf("Error in TX bit %d\n", i);
          exit(-1);
        }
      }
      
      printf("OK TX...");
      
      for (int i=0;i<nof_e_bits;i++) {
        rm_bits_f[i] = rand()%10-5;
        rm_bits_s[i] = (short) rm_bits_f[i];
      }

      bzero(buff_f, BUFFSZ*sizeof(float));
      srslte_rm_turbo_rx(buff_f, BUFFSZ, rm_bits_f, nof_e_bits, bits_f, long_cb_enc, rv_idx, 0);

      bzero(bits2_s, long_cb_enc*sizeof(short));
      srslte_rm_turbo_rx_lut(rm_bits_s, bits2_s, nof_e_bits, cb_idx, rv_idx);

      for (int i=0;i<long_cb_enc;i++) {
        if (bits_f[i] != bits2_s[i]) {
          printf("error RX in bit %d %f!=%d\n", i, bits_f[i], bits2_s[i]);
          exit(-1);
        }
      }
    
      printf("OK RX\n");

    }
  }

  free(rm_bits);
  free(rm_bits2);
  free(rm_bits2_bytes);
  
  exit(0);
}
int main(int argc, char **argv) {
  uint32_t frame_cnt;
  float *llr;
  short *llr_s;
  uint8_t *llr_c;
  uint8_t *data_tx, *data_rx, *data_rx_bytes, *symbols;
  uint32_t i, j;
  float var[SNR_POINTS];
  uint32_t snr_points;
  uint32_t errors;
  uint32_t coded_length;
  struct timeval tdata[3];
  float mean_usec;
  srslte_tdec_t tdec;
  srslte_tcod_t tcod;
  
  parse_args(argc, argv);

  if (!seed) {
    seed = time(NULL);
  }
  srand(seed);

  if (test_known_data) {
    frame_length = KNOWN_DATA_LEN;
  } else {
    frame_length = srslte_cbsegm_cbsize(srslte_cbsegm_cbindex(frame_length));
  }

  coded_length = 3 * (frame_length) + SRSLTE_TCOD_TOTALTAIL;

  printf("  Frame length: %d\n", frame_length);
  if (ebno_db < 100.0) {
    printf("  EbNo: %.2f\n", ebno_db);
  }

  data_tx = srslte_vec_malloc(frame_length * sizeof(uint8_t));
  if (!data_tx) {
    perror("malloc");
    exit(-1);
  }

  data_rx = srslte_vec_malloc(frame_length * sizeof(uint8_t));
  if (!data_rx) {
    perror("malloc");
    exit(-1);
  }
  data_rx_bytes = srslte_vec_malloc(frame_length * sizeof(uint8_t));
  if (!data_rx_bytes) {
    perror("malloc");
    exit(-1);
  }

  symbols = srslte_vec_malloc(coded_length * sizeof(uint8_t));
  if (!symbols) {
    perror("malloc");
    exit(-1);
  }
  llr = srslte_vec_malloc(coded_length * sizeof(float));
  if (!llr) {
    perror("malloc");
    exit(-1);
  }
  llr_s = srslte_vec_malloc(coded_length * sizeof(short));
  if (!llr_s) {
    perror("malloc");
    exit(-1);
  }
  llr_c = srslte_vec_malloc(coded_length * sizeof(uint8_t));
  if (!llr_c) {
    perror("malloc");
    exit(-1);
  }

  if (srslte_tcod_init(&tcod, frame_length)) {
    fprintf(stderr, "Error initiating Turbo coder\n");
    exit(-1);
  }

  if (srslte_tdec_init_manual(&tdec, frame_length, tdec_type)) {
    fprintf(stderr, "Error initiating Turbo decoder\n");
    exit(-1);
  }

  srslte_tdec_force_not_sb(&tdec);

  float ebno_inc, esno_db;
  ebno_inc = (SNR_MAX - SNR_MIN) / SNR_POINTS;
  if (ebno_db == 100.0) {
    snr_points = SNR_POINTS;
    for (i = 0; i < snr_points; i++) {
      ebno_db = SNR_MIN + i * ebno_inc;
      esno_db = ebno_db + 10 * log10((double) 1 / 3);
      var[i] = sqrt(1 / (pow(10, esno_db / 10)));
    }
  } else {
    esno_db = ebno_db + 10 * log10((double) 1 / 3);
    var[0] = sqrt(1 / (pow(10, esno_db / 10)));
    snr_points = 1;
  }
  for (i = 0; i < snr_points; i++) {

    mean_usec = 0;
    errors = 0; 
    frame_cnt = 0;
    while (frame_cnt < nof_frames) {
      /* generate data_tx */
      for (j = 0; j < frame_length; j++) {
        if (test_known_data) {
          data_tx[j] = known_data[j];
        } else {
          data_tx[j] = rand() % 2;
        }
      }

      /* coded BER */
      if (test_known_data) {
        for (j = 0; j < coded_length; j++) {
          symbols[j] = known_data_encoded[j];
        }
      } else {
        srslte_tcod_encode(&tcod, data_tx, symbols, frame_length);
      }

      for (j = 0; j < coded_length; j++) {
        llr[j] = symbols[j] ? 1 : -1;
      }
      srslte_ch_awgn_f(llr, llr, var[i], coded_length);

      for (j=0;j<coded_length;j++) {
        llr_s[j] = (int16_t) (100*llr[j]);
      }

      /* decoder */
      srslte_tdec_new_cb(&tdec, frame_length);

      uint32_t t;
      if (nof_iterations == -1) {
        t = MAX_ITERATIONS;
      } else {
        t = nof_iterations;
      }

      gettimeofday(&tdata[1], NULL); 
      for (int k=0;k<nof_repetitions;k++) { 
        srslte_tdec_run_all(&tdec, llr_s, data_rx_bytes, t, frame_length);
      }
      gettimeofday(&tdata[2], NULL);
      get_time_interval(tdata);
      mean_usec = (tdata[0].tv_sec*1e6+tdata[0].tv_usec)/nof_repetitions;
      
      frame_cnt++;
      uint32_t errors_this = 0; 
      srslte_bit_unpack_vector(data_rx_bytes, data_rx, frame_length);

      errors_this=srslte_bit_diff(data_tx, data_rx, frame_length);
      //printf("error[%d]=%d\n", cb, errors_this);
      errors += errors_this;
      printf("Eb/No: %2.2f %10d/%d   ", SNR_MIN + i * ebno_inc, frame_cnt, nof_frames);
      printf("BER: %.2e  ", (float) errors / (nof_cb*frame_cnt * frame_length));
      printf("%3.1f Mbps (%6.2f usec)", (float) (nof_cb*frame_length) / mean_usec, mean_usec);
      printf("\r");        

    }    
    printf("\n");
  }

  printf("\n");
  if (snr_points == 1) {
    if (errors) {
      printf("%d Errors\n", errors/nof_cb);
    }
  }

  if (data_rx_bytes) {
    free(data_rx_bytes);
  }
  free(data_tx);
  free(symbols);
  free(llr);
  free(llr_c);
  free(llr_s);
  free(data_rx);

  srslte_tdec_free(&tdec);
  srslte_tcod_free(&tcod);

  printf("\n");
  printf("Done\n");
  exit(0);
}