Merge branch 'master' into feature-21-TM7

Conflicts:
	openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
	openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
	openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
	openair1/SCHED/phy_procedures_lte_ue.c
	openair1/SIMULATION/LTE_PHY/dlsim.c
	openair1/SIMULATION/LTE_PHY/mbmssim.c
	targets/RT/USER/Makefile
This commit is contained in:
Xiwen JIANG
2015-10-05 11:27:50 +02:00
1895 changed files with 226357 additions and 505447 deletions
+3 -2
View File
@@ -31,8 +31,9 @@
author: raymond.knopp@eurecom.fr
date: 10.2009
*/
#include "defs.h"
//#include "lte_interleaver_inline.h"
#ifndef TC_MAIN
//#include "defs.h"
#endif
#include "extern_3GPPinterleaver.h"
+531 -349
View File
@@ -1,349 +1,531 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/* file: 3gpplte_sse.c
purpose: Encoding routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
author: Laurent Thomas
maintainer: raymond.knopp@eurecom.fr
date: 09.2012
*/
#include "defs.h"
#include "extern_3GPPinterleaver.h"
#include <stdlib.h>
#include "PHY/sse_intrin.h"
//#define DEBUG_TURBO_ENCODER 1
#define CALLGRIND 1
unsigned short threegpplte_interleaver_output;
unsigned long long threegpplte_interleaver_tmp;
struct treillis {
union {
__m64 systematic_64[3];
char systematic_8[24];
};
union {
__m64 parity1_64[3];
char parity1_8[24];
};
union {
__m64 parity2_64[3];
char parity2_8[24];
};
int exit_state;
} __attribute__ ((aligned(64)));
struct treillis all_treillis[8][256];
int all_treillis_initialized=0;
static inline unsigned char threegpplte_rsc(unsigned char input,unsigned char *state)
{
unsigned char output;
output = (input ^ (*state>>2) ^ (*state>>1))&1;
*state = (((input<<2)^(*state>>1))^((*state>>1)<<2)^((*state)<<2))&7;
return(output);
}
static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z,unsigned char *state)
{
*z = ((*state>>2) ^ (*state)) &1;
*x = ((*state) ^ (*state>>1)) &1;
*state = (*state)>>1;
}
void treillis_table_init(void)
{
//struct treillis t[][]=all_treillis;
//t=memalign(16,sizeof(struct treillis)*8*256);
int i, j,b;
unsigned char v, current_state;
// clear all_treillis
for (i=0; i<8; i++)
bzero( all_treillis[i], sizeof(all_treillis[0]) );
for (i=0; i<8; i++) { //all possible initial states
for (j=0; j<=255; j++) { // all possible values of a byte
current_state=i;
for (b=0; b<8 ; b++ ) { // pre-compute the image of the byte j in _m128i vector right place
all_treillis[i][j].systematic_8[b*3]= (j&(1<<(7-b)))>>(7-b);
v=threegpplte_rsc( all_treillis[i][j].systematic_8[b*3] ,
&current_state);
all_treillis[i][j].parity1_8[b*3+1]=v; // for the yparity1
all_treillis[i][j].parity2_8[b*3+2]=v; // for the yparity2
}
all_treillis[i][j].exit_state=current_state;
}
}
all_treillis_initialized=1;
return ;
}
char interleave_compact_byte(short * base_interleaver,unsigned char * input, unsigned char * output, int n)
{
char expandInput[768*8] __attribute__((aligned(16)));
int i,loop=n>>4;
__m128i *i_128=(__m128i *)input, *o_128=(__m128i*)expandInput;
__m128i tmp1, tmp2, tmp3, tmp4;
__m128i BIT_MASK = _mm_set_epi8( 0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000);
if ((n&15) > 0)
loop++;
for (i=0; i<loop ; i++ ) {
/* int cur_byte=i<<3; */
/* for (b=0;b<8;b++) */
/* expandInput[cur_byte+b] = (input[i]&(1<<(7-b)))>>(7-b); */
tmp1=_mm_load_si128(i_128++);
tmp2=_mm_unpacklo_epi8(tmp1,tmp1);
tmp3=_mm_unpacklo_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp3=_mm_unpackhi_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp2=_mm_unpackhi_epi8(tmp1,tmp1);
tmp3=_mm_unpacklo_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp3=_mm_unpackhi_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
}
short * ptr_intl=base_interleaver;
__m128i tmp;
int input_length_words=n>>1;
unsigned short * systematic2_ptr=(unsigned short *) output;
// int j;
for ( i=0; i< input_length_words ; i ++ ) {
// for (j=0;j<16;j++) printf("%d(%d).",ptr_intl[j],expandInput[ptr_intl[j]]);
// printf("\n");
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],7);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],6);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],5);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],4);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],3);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],2);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],1);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],0);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+7);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+6);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+5);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+4);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+3);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+2);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+1);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+0);
*systematic2_ptr++=(unsigned short)_mm_movemask_epi8(tmp);
}
return n;
}
#define _mm_expand_si128(xmmx, out, bit_mask) \
{ \
__m128i loc_mm; \
loc_mm=(xmmx); \
loc_mm=_mm_and_si128(loc_mm,bit_mask); \
out=_mm_cmpeq_epi8(loc_mm,bit_mask); \
}
void threegpplte_turbo_encoder(unsigned char *input,
unsigned short input_length_bytes,
unsigned char *output,
unsigned char F,
unsigned short interleaver_f1,
unsigned short interleaver_f2)
{
int i;
unsigned char *x;
unsigned char state0=0,state1=0;
unsigned short input_length_bits = input_length_bytes<<3;
short * base_interleaver;
if ( all_treillis_initialized == 0 )
treillis_table_init();
// look for f1 and f2 precomputed interleaver values
for (i=0; i < 188 && f1f2mat[i].nb_bits != input_length_bits; i++);
if ( i == 188 ) {
msg("Illegal frame length!\n");
return;
} else {
base_interleaver=il_tb+f1f2mat[i].beg_index;
}
unsigned char systematic2[768];
interleave_compact_byte(base_interleaver,input,systematic2,input_length_bytes);
__m64 *ptr_output=(__m64*) output;
unsigned char cur_s1, cur_s2;
int code_rate;
for ( state0=state1=i=0 ; i<input_length_bytes; i++ ) {
cur_s1=input[i];
cur_s2=systematic2[i];
for ( code_rate=0; code_rate<3; code_rate++) {
*ptr_output++ = _mm_add_pi8(all_treillis[state0][cur_s1].systematic_64[code_rate],
_mm_add_pi8(all_treillis[state0][cur_s1].parity1_64[code_rate],
all_treillis[state1][cur_s2].parity2_64[code_rate]));
}
state0=all_treillis[state0][cur_s1].exit_state;
state1=all_treillis[state1][cur_s2].exit_state;
}
x=output+(input_length_bits*3);
// Trellis termination
threegpplte_rsc_termination(&x[0],&x[1],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[0],x[1],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[2],&x[3],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[2],x[3],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[4],&x[5],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[4],x[5],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[6],&x[7],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[6],x[7],state1);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[8],&x[9],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[8],x[9],state1);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[10],&x[11],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[10],x[11],state1);
#endif //DEBUG_TURBO_ENCODER
_mm_empty();
_m_empty();
}
#ifdef MAIN
#define INPUT_LENGTH 5
#define F1 3
#define F2 10
int main(int argc,char **argv)
{
unsigned char input[INPUT_LENGTH],state,state2;
unsigned char output[12+(3*(INPUT_LENGTH<<3))],x,z;
int i;
unsigned char out;
for (state=0; state<8; state++) {
for (i=0; i<2; i++) {
state2=state;
out = threegpplte_rsc(i,&state2);
printf("State (%d->%d) : (%d,%d)\n",state,state2,i,out);
}
}
printf("\n");
for (state=0; state<8; state++) {
state2=state;
threegpplte_rsc_termination(&x,&z,&state2);
printf("Termination: (%d->%d) : (%d,%d)\n",state,state2,x,z);
}
for (i=0; i<5; i++) {
input[i] = i*219;
printf("Input %d : %x\n",i,input[i]);
}
threegpplte_turbo_encoder(&input[0],
5,
&output[0],
F1,
F2);
return(0);
}
#endif // MAIN
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/* file: 3gpplte_sse.c
purpose: Encoding routines for implementing Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
author: Laurent Thomas
maintainer: raymond.knopp@eurecom.fr
date: 09.2012
*/
#ifndef TC_MAIN
#include "defs.h"
#include "extern_3GPPinterleaver.h"
#else
#include "vars.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "PHY/sse_intrin.h"
#define print_bytes(s,x) printf("%s %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7],(x)[8],(x)[9],(x)[10],(x)[11],(x)[12],(x)[13],(x)[14],(x)[15])
#define print_shorts(s,x) printf("%s %x,%x,%x,%x,%x,%x,%x,%x\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
#define print_ints(s,x) printf("%s %x %x %x %x\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
//#define DEBUG_TURBO_ENCODER 1
#define CALLGRIND 1
unsigned short threegpplte_interleaver_output;
unsigned long long threegpplte_interleaver_tmp;
#if defined(__x86_64__) || defined(__i386__)
struct treillis {
union {
__m64 systematic_64[3];
char systematic_8[24];
};
union {
__m64 parity1_64[3];
char parity1_8[24];
};
union {
__m64 parity2_64[3];
char parity2_8[24];
};
int exit_state;
} __attribute__ ((aligned(64)));
#elif defined(__arm__)
struct treillis {
union {
uint8x8_t systematic_64[3];
char systematic_8[24];
}__attribute__((aligned(64)));
union {
uint8x8_t parity1_64[3];
char parity1_8[24];
}__attribute__((aligned(64)));
union {
uint8x8_t parity2_64[3];
char parity2_8[24];
}__attribute__((aligned(64)));
int exit_state;
};
#endif
struct treillis all_treillis[8][256];
int all_treillis_initialized=0;
static inline unsigned char threegpplte_rsc(unsigned char input,unsigned char *state)
{
unsigned char output;
output = (input ^ (*state>>2) ^ (*state>>1))&1;
*state = (((input<<2)^(*state>>1))^((*state>>1)<<2)^((*state)<<2))&7;
return(output);
}
static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z,unsigned char *state)
{
*z = ((*state>>2) ^ (*state)) &1;
*x = ((*state) ^ (*state>>1)) &1;
*state = (*state)>>1;
}
void treillis_table_init(void)
{
//struct treillis t[][]=all_treillis;
//t=memalign(16,sizeof(struct treillis)*8*256);
int i, j,b;
unsigned char v, current_state;
// clear all_treillis
for (i=0; i<8; i++)
bzero( all_treillis[i], sizeof(all_treillis[0]) );
for (i=0; i<8; i++) { //all possible initial states
for (j=0; j<=255; j++) { // all possible values of a byte
current_state=i;
for (b=0; b<8 ; b++ ) { // pre-compute the image of the byte j in _m128i vector right place
all_treillis[i][j].systematic_8[b*3]= (j&(1<<(7-b)))>>(7-b);
v=threegpplte_rsc( all_treillis[i][j].systematic_8[b*3] ,
&current_state);
all_treillis[i][j].parity1_8[b*3+1]=v; // for the yparity1
all_treillis[i][j].parity2_8[b*3+2]=v; // for the yparity2
}
all_treillis[i][j].exit_state=current_state;
}
}
all_treillis_initialized=1;
return ;
}
char interleave_compact_byte(short * base_interleaver,unsigned char * input, unsigned char * output, int n)
{
char expandInput[768*8] __attribute__((aligned(16)));
int i,loop=n>>4;
#if defined(__x86_64__) || defined(__i386__)
__m128i *i_128=(__m128i *)input, *o_128=(__m128i*)expandInput;
__m128i tmp1, tmp2, tmp3, tmp4;
__m128i BIT_MASK = _mm_set_epi8( 0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000);
#elif defined(__arm__)
uint8x16_t *i_128=(uint8x16_t *)input, *o_128=(uint8x16_t *)expandInput;
uint8x16_t tmp1,tmp2;
uint16x8_t tmp3;
uint32x4_t tmp4;
uint8x16_t and_tmp;
uint8x16_t BIT_MASK = { 0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001};
#endif
if ((n&15) > 0)
loop++;
for (i=0; i<loop ; i++ ) {
/* int cur_byte=i<<3; */
/* for (b=0;b<8;b++) */
/* expandInput[cur_byte+b] = (input[i]&(1<<(7-b)))>>(7-b); */
#if defined(__x86_64__) || defined(__i386__)
tmp1=_mm_load_si128(i_128++);
tmp2=_mm_unpacklo_epi8(tmp1,tmp1);
tmp3=_mm_unpacklo_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp3=_mm_unpackhi_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp2=_mm_unpackhi_epi8(tmp1,tmp1);
tmp3=_mm_unpacklo_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp3=_mm_unpackhi_epi16(tmp2,tmp2);
tmp4=_mm_unpacklo_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
tmp4=_mm_unpackhi_epi32(tmp3,tmp3);
*o_128++=_mm_cmpeq_epi8(_mm_and_si128(tmp4,BIT_MASK),BIT_MASK);;
#elif defined(__arm__)
tmp1=vld1q_u8((uint8_t*)i_128);
//print_bytes("tmp1:",(uint8_t*)&tmp1);
uint8x16x2_t temp1 = vzipq_u8(tmp1,tmp1);
tmp2 = temp1.val[0];
uint16x8x2_t temp2 = vzipq_u16((uint16x8_t)tmp2,(uint16x8_t)tmp2);
tmp3 = temp2.val[0];
uint32x4x2_t temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //1
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //2
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp3 = temp2.val[1];
temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //3
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //4
//and_tmp = vandq_u8((uint8x16_t)tmp4,BIT_MASK); print_bytes("and:",and_tmp);
//print_bytes("o:",(uint8_t*)(o_128-1));
temp1 = vzipq_u8(tmp1,tmp1);
tmp2 = temp1.val[1];
temp2 = vzipq_u16((uint16x8_t)tmp2,(uint16x8_t)tmp2);
tmp3 = temp2.val[0];
temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //5
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //6
//print_bytes("o:",(uint8_t*)(o_128-1));
temp2 = vzipq_u16((uint16x8_t)tmp2,(uint16x8_t)tmp2);
tmp3 = temp2.val[1];
temp3 = vzipq_u32((uint32x4_t)tmp3,(uint32x4_t)tmp3);
tmp4 = temp3.val[0];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //7
//print_bytes("o:",(uint8_t*)(o_128-1));
tmp4 = temp3.val[1];
//print_bytes("tmp4:",(uint8_t*)&tmp4);
*o_128++=vceqq_u8(vandq_u8((uint8x16_t)tmp4,BIT_MASK),BIT_MASK); //7
//print_bytes("o:",(uint8_t*)(o_128-1));
i_128++;
#endif
}
short * ptr_intl=base_interleaver;
#if defined(__x86_64) || defined(__i386__)
__m128i tmp;
uint16_t *systematic2_ptr=(unsigned short *) output;
#elif defined(__arm__)
uint8x16_t tmp;
const uint8_t __attribute__ ((aligned (16))) _Powers[16]=
{ 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 };
// Set the powers of 2 (do it once for all, if applicable)
uint8x16_t Powers= vld1q_u8(_Powers);
uint8_t *systematic2_ptr=(uint8_t *) output;
#endif
int input_length_words=n>>1;
for ( i=0; i< input_length_words ; i ++ ) {
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],7);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],6);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],5);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],4);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],3);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],2);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],1);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],0);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+7);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+6);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+5);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+4);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+3);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+2);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+1);
tmp=_mm_insert_epi8(tmp,expandInput[*ptr_intl++],8+0);
*systematic2_ptr++=(unsigned short)_mm_movemask_epi8(tmp);
#elif defined(__arm__)
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,7);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,6);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,5);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,4);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,3);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,2);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,1);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,0);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+7);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+6);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+5);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+4);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+3);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+2);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+1);
tmp=vsetq_lane_u8(expandInput[*ptr_intl++],tmp,8+0);
// Compute the mask from the input
uint64x2_t Mask= vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(tmp, Powers))));
vst1q_lane_u8(systematic2_ptr++, (uint8x16_t)Mask, 0);
vst1q_lane_u8(systematic2_ptr++, (uint8x16_t)Mask, 8);
#endif
}
return n;
}
/*
#define _mm_expand_si128(xmmx, out, bit_mask) \
{ \
__m128i loc_mm; \
loc_mm=(xmmx); \
loc_mm=_mm_and_si128(loc_mm,bit_mask); \
out=_mm_cmpeq_epi8(loc_mm,bit_mask); \
}
*/
void threegpplte_turbo_encoder(unsigned char *input,
unsigned short input_length_bytes,
unsigned char *output,
unsigned char F,
unsigned short interleaver_f1,
unsigned short interleaver_f2)
{
int i;
unsigned char *x;
unsigned char state0=0,state1=0;
unsigned short input_length_bits = input_length_bytes<<3;
short * base_interleaver;
if ( all_treillis_initialized == 0 )
treillis_table_init();
// look for f1 and f2 precomputed interleaver values
for (i=0; i < 188 && f1f2mat[i].nb_bits != input_length_bits; i++);
if ( i == 188 ) {
printf("Illegal frame length!\n");
return;
} else {
base_interleaver=il_tb+f1f2mat[i].beg_index;
}
unsigned char systematic2[768];
interleave_compact_byte(base_interleaver,input,systematic2,input_length_bytes);
#if defined(__x86_64__) || defined(__i386__)
__m64 *ptr_output=(__m64*) output;
#elif defined(__arm__)
uint8x8_t *ptr_output=(uint8x8_t*)output;
#endif
unsigned char cur_s1, cur_s2;
int code_rate;
for ( state0=state1=i=0 ; i<input_length_bytes; i++ ) {
cur_s1=input[i];
cur_s2=systematic2[i];
for ( code_rate=0; code_rate<3; code_rate++) {
#if defined(__x86_64__) || defined(__i386__)
*ptr_output++ = _mm_add_pi8(all_treillis[state0][cur_s1].systematic_64[code_rate],
_mm_add_pi8(all_treillis[state0][cur_s1].parity1_64[code_rate],
all_treillis[state1][cur_s2].parity2_64[code_rate]));
#elif defined(__arm__)
uint8x8_t ptmp = vadd_u8(all_treillis[state0][cur_s1].parity1_64[code_rate],
all_treillis[state1][cur_s2].parity2_64[code_rate]);
*ptr_output++ = vadd_u8(all_treillis[state0][cur_s1].systematic_64[code_rate],
ptmp);
#endif
}
state0=all_treillis[state0][cur_s1].exit_state;
state1=all_treillis[state1][cur_s2].exit_state;
}
x=output+(input_length_bits*3);
// Trellis termination
threegpplte_rsc_termination(&x[0],&x[1],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[0],x[1],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[2],&x[3],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[2],x[3],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[4],&x[5],&state0);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state0 %d\n",x[4],x[5],state0);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[6],&x[7],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[6],x[7],state1);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[8],&x[9],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[8],x[9],state1);
#endif //DEBUG_TURBO_ENCODER
threegpplte_rsc_termination(&x[10],&x[11],&state1);
#ifdef DEBUG_TURBO_ENCODER
printf("term: x0 %d, x1 %d, state1 %d\n",x[10],x[11],state1);
#endif //DEBUG_TURBO_ENCODER
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
#ifdef TC_MAIN
#define INPUT_LENGTH 20
#define F1 21
#define F2 120
int main(int argc,char **argv)
{
unsigned char input[INPUT_LENGTH+16],state,state2;
unsigned char output[12+(3*(INPUT_LENGTH<<3))],x,z;
int i;
unsigned char out;
for (state=0; state<8; state++) {
for (i=0; i<2; i++) {
state2=state;
out = threegpplte_rsc(i,&state2);
printf("State (%d->%d) : (%d,%d)\n",state,state2,i,out);
}
}
printf("\n");
for (state=0; state<8; state++) {
state2=state;
threegpplte_rsc_termination(&x,&z,&state2);
printf("Termination: (%d->%d) : (%d,%d)\n",state,state2,x,z);
}
memset((void*)input,0,INPUT_LENGTH+16);
for (i=0; i<INPUT_LENGTH; i++) {
input[i] = i*219;
printf("Input %d : %x\n",i,input[i]);
}
threegpplte_turbo_encoder(&input[0],
INPUT_LENGTH,
&output[0],
0,
F1,
F2);
for (i=0;i<12+(INPUT_LENGTH*24);i++)
printf("%d",output[i]);
printf("\n");
return(0);
}
#endif // MAIN
@@ -64,6 +64,8 @@
#endif
#define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
//#define DEBUG_LOGMAP
@@ -120,10 +122,17 @@ void compute_gamma16(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity
unsigned short frame_length,unsigned char term_flag)
{
int k,K1;
#if defined(__x86_64__)||defined(__i386__)
__m128i *systematic128 = (__m128i *)systematic;
__m128i *y_parity128 = (__m128i *)y_parity;
__m128i *m10_128 = (__m128i *)m10;
__m128i *m11_128 = (__m128i *)m11;
#elif defined(__arm__)
int16x8_t *systematic128 = (int16x8_t *)systematic;
int16x8_t *y_parity128 = (int16x8_t *)y_parity;
int16x8_t *m10_128 = (int16x8_t *)m10;
int16x8_t *m11_128 = (int16x8_t *)m11;
#endif
#ifdef DEBUG_LOGMAP
msg("compute_gamma, %p,%p,%p,%p,framelength %d\n",m11,m10,systematic,y_parity,frame_length);
@@ -132,61 +141,31 @@ void compute_gamma16(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity
K1=frame_length>>3;
for (k=0; k<K1; k++) {
#if defined(__x86_64__) || defined(__i386__)
m11_128[k] = _mm_srai_epi16(_mm_adds_epi16(systematic128[k],y_parity128[k]),1);
m10_128[k] = _mm_srai_epi16(_mm_subs_epi16(systematic128[k],y_parity128[k]),1);
/*
printf("gamma %d: s %d,%d,%d,%d,%d,%d,%d,%d\n",
k,
(int16_t)_mm_extract_epi16(systematic128[k],0),
(int16_t)_mm_extract_epi16(systematic128[k],1),
(int16_t)_mm_extract_epi16(systematic128[k],2),
(int16_t)_mm_extract_epi16(systematic128[k],3),
(int16_t)_mm_extract_epi16(systematic128[k],4),
(int16_t)_mm_extract_epi16(systematic128[k],5),
(int16_t)_mm_extract_epi16(systematic128[k],6),
(int16_t)_mm_extract_epi16(systematic128[k],7));
printf("gamma %d: yp %d,%d,%d,%d,%d,%d,%d,%d\n",
k,
(int16_t)_mm_extract_epi16(y_parity128[k],0),
(int16_t)_mm_extract_epi16(y_parity128[k],1),
(int16_t)_mm_extract_epi16(y_parity128[k],2),
(int16_t)_mm_extract_epi16(y_parity128[k],3),
(int16_t)_mm_extract_epi16(y_parity128[k],4),
(int16_t)_mm_extract_epi16(y_parity128[k],5),
(int16_t)_mm_extract_epi16(y_parity128[k],6),
(int16_t)_mm_extract_epi16(y_parity128[k],7));
printf("gamma %d: m11 %d,%d,%d,%d,%d,%d,%d,%d\n",
k,
(int16_t)_mm_extract_epi16(m11_128[k],0),
(int16_t)_mm_extract_epi16(m11_128[k],1),
(int16_t)_mm_extract_epi16(m11_128[k],2),
(int16_t)_mm_extract_epi16(m11_128[k],3),
(int16_t)_mm_extract_epi16(m11_128[k],4),
(int16_t)_mm_extract_epi16(m11_128[k],5),
(int16_t)_mm_extract_epi16(m11_128[k],6),
(int16_t)_mm_extract_epi16(m11_128[k],7));
printf("gamma %d: m10 %d,%d,%d,%d,%d,%d,%d,%d\n",
k,
(int16_t)_mm_extract_epi16(m10_128[k],0),
(int16_t)_mm_extract_epi16(m10_128[k],1),
(int16_t)_mm_extract_epi16(m10_128[k],2),
(int16_t)_mm_extract_epi16(m10_128[k],3),
(int16_t)_mm_extract_epi16(m10_128[k],4),
(int16_t)_mm_extract_epi16(m10_128[k],5),
(int16_t)_mm_extract_epi16(m10_128[k],6),
(int16_t)_mm_extract_epi16(m10_128[k],7));
*/
#elif defined(__arm__)
m11_128[k] = vhaddq_s16(systematic128[k],y_parity128[k]);
m10_128[k] = vhsubq_s16(systematic128[k],y_parity128[k]);
#endif
#ifdef DEBUG_LOGMAP
printf("Loop index k, m11,m10\n");
print_shorts("sys",(int16_t*)&systematic128[k]);
print_shorts("yp",(int16_t*)&y_parity128[k]);
print_shorts("m11",(int16_t*)&m11_128[k]);
print_shorts("m10",(int16_t*)&m10_128[k]);
#endif
}
// Termination
#if defined(__x86_64__) || defined(__i386__)
m11_128[k] = _mm_srai_epi16(_mm_adds_epi16(systematic128[k+term_flag],y_parity128[k]),1);
m10_128[k] = _mm_srai_epi16(_mm_subs_epi16(systematic128[k+term_flag],y_parity128[k]),1);
// printf("gamma (term): %d,%d, %d,%d, %d,%d\n",m11[k<<3],m10[k<<3],m11[1+(k<<3)],m10[1+(k<<3)],m11[2+(k<<3)],m10[2+(k<<3)]);
#elif defined(__arm__)
m11_128[k] = vhaddq_s16(systematic128[k+term_flag],y_parity128[k]);
m10_128[k] = vhsubq_s16(systematic128[k+term_flag],y_parity128[k]);
#endif
}
#define L 40
@@ -194,19 +173,31 @@ void compute_gamma16(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity
void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned short frame_length,unsigned char F)
{
int k,l,l2,K1,rerun_flag=0;
#if defined(__x86_64__) || defined(__i386__)
__m128i *alpha128=(__m128i *)alpha,*alpha_ptr;
__m128i a0,a1,a2,a3,a4,a5,a6,a7,*m11p,*m10p;
__m128i m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
__m128i new0,new1,new2,new3,new4,new5,new6,new7;
__m128i alpha_max;
#elif defined(__arm__)
int16x8_t *alpha128=(int16x8_t *)alpha,*alpha_ptr;
int16x8_t a0,a1,a2,a3,a4,a5,a6,a7,*m11p,*m10p;
int16x8_t m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
int16x8_t new0,new1,new2,new3,new4,new5,new6,new7;
int16x8_t alpha_max;
#endif
l2 = L>>3;
K1 = (frame_length>>3);
for (l=K1;; l=l2,rerun_flag=1) {
#if defined(__x86_64__) || defined(__i386__)
alpha128 = (__m128i *)alpha;
#elif defined(__arm__)
alpha128 = (int16x8_t *)alpha;
#endif
if (rerun_flag == 0) {
#if defined(__x86_64__) || defined(__i386__)
alpha128[0] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,0);
alpha128[1] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
alpha128[2] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
@@ -215,8 +206,31 @@ void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned s
alpha128[5] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
alpha128[6] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
alpha128[7] = _mm_set_epi16(-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2,-MAX/2);
#elif defined(__arm__)
alpha128[0] = vdupq_n_s16(-MAX/2);
alpha128[0] = vsetq_lane_s16(0,alpha128[0],0);
alpha128[1] = vdupq_n_s16(-MAX/2);
alpha128[2] = vdupq_n_s16(-MAX/2);
alpha128[3] = vdupq_n_s16(-MAX/2);
alpha128[4] = vdupq_n_s16(-MAX/2);
alpha128[5] = vdupq_n_s16(-MAX/2);
alpha128[6] = vdupq_n_s16(-MAX/2);
alpha128[7] = vdupq_n_s16(-MAX/2);
#endif
#ifdef DEBUG_LOGMAP
printf("Initial alpha\n");
print_shorts("a0",(int16_t*)&alpha128[0]);
print_shorts("a1",(int16_t*)&alpha128[1]);
print_shorts("a2",(int16_t*)&alpha128[2]);
print_shorts("a3",(int16_t*)&alpha128[3]);
print_shorts("a4",(int16_t*)&alpha128[4]);
print_shorts("a5",(int16_t*)&alpha128[5]);
print_shorts("a6",(int16_t*)&alpha128[6]);
print_shorts("a7",(int16_t*)&alpha128[7]);
#endif
} else {
//set initial alpha in columns 1-7 from final alpha from last run in columns 0-6
#if defined(__x86_64__) || defined(__i386__)
alpha128[0] = _mm_slli_si128(alpha128[frame_length],2);
alpha128[1] = _mm_slli_si128(alpha128[1+frame_length],2);
alpha128[2] = _mm_slli_si128(alpha128[2+frame_length],2);
@@ -225,6 +239,16 @@ void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned s
alpha128[5] = _mm_slli_si128(alpha128[5+frame_length],2);
alpha128[6] = _mm_slli_si128(alpha128[6+frame_length],2);
alpha128[7] = _mm_slli_si128(alpha128[7+frame_length],2);
#elif defined(__arm__)
alpha128[0] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[frame_length],16); alpha128[0] = vsetq_lane_s16(alpha[8],alpha128[0],3);
alpha128[1] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[1+frame_length],16); alpha128[1] = vsetq_lane_s16(alpha[24],alpha128[0],3);
alpha128[2] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[2+frame_length],16); alpha128[2] = vsetq_lane_s16(alpha[40],alpha128[0],3);
alpha128[3] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[3+frame_length],16); alpha128[3] = vsetq_lane_s16(alpha[56],alpha128[0],3);
alpha128[4] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[4+frame_length],16); alpha128[4] = vsetq_lane_s16(alpha[72],alpha128[0],3);
alpha128[5] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[5+frame_length],16); alpha128[5] = vsetq_lane_s16(alpha[88],alpha128[0],3);
alpha128[6] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[6+frame_length],16); alpha128[6] = vsetq_lane_s16(alpha[104],alpha128[0],3);
alpha128[7] = (int16x8_t)vshlq_n_s64((int64x2_t)alpha128[7+frame_length],16); alpha128[7] = vsetq_lane_s16(alpha[120],alpha128[0],3);
#endif
// set initial alpha in column 0 to (0,-MAX/2,...,-MAX/2)
alpha[8] = -MAX/2;
alpha[16] = -MAX/2;
@@ -233,17 +257,33 @@ void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned s
alpha[40] = -MAX/2;
alpha[48] = -MAX/2;
alpha[56] = -MAX/2;
#ifdef DEBUG_LOGMAP
printf("Second run\n");
print_shorts("a0",(int16_t*)&alpha128[0]);
print_shorts("a1",(int16_t*)&alpha128[1]);
print_shorts("a2",(int16_t*)&alpha128[2]);
print_shorts("a3",(int16_t*)&alpha128[3]);
print_shorts("a4",(int16_t*)&alpha128[4]);
print_shorts("a5",(int16_t*)&alpha128[5]);
print_shorts("a6",(int16_t*)&alpha128[6]);
print_shorts("a7",(int16_t*)&alpha128[7]);
#endif
}
alpha_ptr = &alpha128[0];
#if defined(__x86_64__) || defined(__i386__)
m11p = (__m128i*)m_11;
m10p = (__m128i*)m_10;
#elif defined(__arm__)
m11p = (int16x8_t*)m_11;
m10p = (int16x8_t*)m_10;
#endif
for (k=0;
k<l;
k++) {
#if defined(__x86_64__) || defined(__i386__)
a1=_mm_load_si128(&alpha_ptr[1]);
a3=_mm_load_si128(&alpha_ptr[3]);
a5=_mm_load_si128(&alpha_ptr[5]);
@@ -288,10 +328,48 @@ void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned s
alpha_max = _mm_max_epi16(alpha_max,a5);
alpha_max = _mm_max_epi16(alpha_max,a6);
alpha_max = _mm_max_epi16(alpha_max,a7);
#elif defined(__arm__)
m_b0 = vqaddq_s16(alpha_ptr[1],*m11p); // m11
m_b4 = vqsubq_s16(alpha_ptr[1],*m11p); // m00=-m11
m_b1 = vqsubq_s16(alpha_ptr[3],*m10p); // m01=-m10
m_b5 = vqaddq_s16(alpha_ptr[3],*m10p); // m10
m_b2 = vqaddq_s16(alpha_ptr[5],*m10p); // m10
m_b6 = vqsubq_s16(alpha_ptr[5],*m10p); // m01=-m10
m_b3 = vqsubq_s16(alpha_ptr[7],*m11p); // m00=-m11
m_b7 = vqaddq_s16(alpha_ptr[7],*m11p); // m11
new0 = vqsubq_s16(alpha_ptr[0],*m11p); // m00=-m11
new4 = vqaddq_s16(alpha_ptr[0],*m11p); // m11
new1 = vqaddq_s16(alpha_ptr[2],*m10p); // m10
new5 = vqsubq_s16(alpha_ptr[2],*m10p); // m01=-m10
new2 = vqsubq_s16(alpha_ptr[4],*m10p); // m01=-m10
new6 = vqaddq_s16(alpha_ptr[4],*m10p); // m10
new3 = vqaddq_s16(alpha_ptr[6],*m11p); // m11
new7 = vqsubq_s16(alpha_ptr[6],*m11p); // m00=-m11
a0 = vmaxq_s16(m_b0,new0);
a1 = vmaxq_s16(m_b1,new1);
a2 = vmaxq_s16(m_b2,new2);
a3 = vmaxq_s16(m_b3,new3);
a4 = vmaxq_s16(m_b4,new4);
a5 = vmaxq_s16(m_b5,new5);
a6 = vmaxq_s16(m_b6,new6);
a7 = vmaxq_s16(m_b7,new7);
// compute and subtract maxima
alpha_max = vmaxq_s16(a0,a1);
alpha_max = vmaxq_s16(alpha_max,a2);
alpha_max = vmaxq_s16(alpha_max,a3);
alpha_max = vmaxq_s16(alpha_max,a4);
alpha_max = vmaxq_s16(alpha_max,a5);
alpha_max = vmaxq_s16(alpha_max,a6);
alpha_max = vmaxq_s16(alpha_max,a7);
#endif
alpha_ptr+=8;
m11p++;
m10p++;
#if defined(__x86_64__) || defined(__i386__)
alpha_ptr[0] = _mm_subs_epi16(a0,alpha_max);
alpha_ptr[1] = _mm_subs_epi16(a1,alpha_max);
alpha_ptr[2] = _mm_subs_epi16(a2,alpha_max);
@@ -300,6 +378,58 @@ void compute_alpha16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned s
alpha_ptr[5] = _mm_subs_epi16(a5,alpha_max);
alpha_ptr[6] = _mm_subs_epi16(a6,alpha_max);
alpha_ptr[7] = _mm_subs_epi16(a7,alpha_max);
#elif defined(__arm__)
alpha_ptr[0] = vqsubq_s16(a0,alpha_max);
alpha_ptr[1] = vqsubq_s16(a1,alpha_max);
alpha_ptr[2] = vqsubq_s16(a2,alpha_max);
alpha_ptr[3] = vqsubq_s16(a3,alpha_max);
alpha_ptr[4] = vqsubq_s16(a4,alpha_max);
alpha_ptr[5] = vqsubq_s16(a5,alpha_max);
alpha_ptr[6] = vqsubq_s16(a6,alpha_max);
alpha_ptr[7] = vqsubq_s16(a7,alpha_max);
#endif
#ifdef DEBUG_LOGMAP
printf("Loop index %d, mb\n",k);
print_shorts("mb0",(int16_t*)&m_b0);
print_shorts("mb1",(int16_t*)&m_b1);
print_shorts("mb2",(int16_t*)&m_b2);
print_shorts("mb3",(int16_t*)&m_b3);
print_shorts("mb4",(int16_t*)&m_b4);
print_shorts("mb5",(int16_t*)&m_b5);
print_shorts("mb6",(int16_t*)&m_b6);
print_shorts("mb7",(int16_t*)&m_b7);
printf("Loop index %d, new\n",k);
print_shorts("new0",(int16_t*)&new0);
print_shorts("new1",(int16_t*)&new1);
print_shorts("new2",(int16_t*)&new2);
print_shorts("new3",(int16_t*)&new3);
print_shorts("new4",(int16_t*)&new4);
print_shorts("new5",(int16_t*)&new5);
print_shorts("new6",(int16_t*)&new6);
print_shorts("new7",(int16_t*)&new7);
printf("Loop index %d, after max\n",k);
print_shorts("a0",(int16_t*)&a0);
print_shorts("a1",(int16_t*)&a1);
print_shorts("a2",(int16_t*)&a2);
print_shorts("a3",(int16_t*)&a3);
print_shorts("a4",(int16_t*)&a4);
print_shorts("a5",(int16_t*)&a5);
print_shorts("a6",(int16_t*)&a6);
print_shorts("a7",(int16_t*)&a7);
printf("Loop index %d\n",k);
print_shorts("a0",(int16_t*)&alpha_ptr[0]);
print_shorts("a1",(int16_t*)&alpha_ptr[1]);
print_shorts("a2",(int16_t*)&alpha_ptr[2]);
print_shorts("a3",(int16_t*)&alpha_ptr[3]);
print_shorts("a4",(int16_t*)&alpha_ptr[4]);
print_shorts("a5",(int16_t*)&alpha_ptr[5]);
print_shorts("a6",(int16_t*)&alpha_ptr[6]);
print_shorts("a7",(int16_t*)&alpha_ptr[7]);
#endif
}
@@ -313,12 +443,22 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
{
int k,rerun_flag=0;
#if defined(__x86_64__) || defined(__i386__)
__m128i m11_128,m10_128;
__m128i m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
__m128i new0,new1,new2,new3,new4,new5,new6,new7;
__m128i *beta128,*alpha128,*beta_ptr;
__m128i beta_max;
#elif defined(__arm__)
int16x8_t m11_128,m10_128;
int16x8_t m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
int16x8_t new0,new1,new2,new3,new4,new5,new6,new7;
int16x8_t *beta128,*alpha128,*beta_ptr;
int16x8_t beta_max;
#endif
int16_t m11,m10,beta0_16,beta1_16,beta2_16,beta3_16,beta4_16,beta5_16,beta6_16,beta7_16,beta0_2,beta1_2,beta2_2,beta3_2,beta_m;
llr_t beta0,beta1;
@@ -380,9 +520,13 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
beta7_16=beta7_16-beta_m;
for (rerun_flag=0;; rerun_flag=1) {
#if defined(__x86_64__) || defined(__i386__)
beta_ptr = (__m128i*)&beta[frame_length<<3];
alpha128 = (__m128i*)&alpha[0];
#elif defined(__arm__)
beta_ptr = (int16x8_t*)&beta[frame_length<<3];
alpha128 = (int16x8_t*)&alpha[0];
#endif
if (rerun_flag == 0) {
beta_ptr[0] = alpha128[(frame_length)];
beta_ptr[1] = alpha128[1+(frame_length)];
@@ -393,6 +537,7 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
beta_ptr[6] = alpha128[6+(frame_length)];
beta_ptr[7] = alpha128[7+(frame_length)];
} else {
#if defined(__x86_64__) || defined(__i386__)
beta128 = (__m128i*)&beta[0];
beta_ptr[0] = _mm_srli_si128(beta128[0],2);
beta_ptr[1] = _mm_srli_si128(beta128[1],2);
@@ -402,9 +547,22 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
beta_ptr[5] = _mm_srli_si128(beta128[5],2);
beta_ptr[6] = _mm_srli_si128(beta128[6],2);
beta_ptr[7] = _mm_srli_si128(beta128[7],2);
#elif defined(__arm__)
beta128 = (int16x8_t*)&beta[0];
beta_ptr = (int16x8_t*)&beta[frame_length<<3];
beta_ptr[0] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[0],16); beta_ptr[0] = vsetq_lane_s16(beta[3],beta_ptr[0],4);
beta_ptr[1] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[1],16); beta_ptr[1] = vsetq_lane_s16(beta[11],beta_ptr[1],4);
beta_ptr[2] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[2],16); beta_ptr[2] = vsetq_lane_s16(beta[19],beta_ptr[2],4);
beta_ptr[3] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[3],16); beta_ptr[3] = vsetq_lane_s16(beta[27],beta_ptr[3],4);
beta_ptr[4] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[4],16); beta_ptr[4] = vsetq_lane_s16(beta[35],beta_ptr[4],4);
beta_ptr[5] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[5],16); beta_ptr[5] = vsetq_lane_s16(beta[43],beta_ptr[5],4);
beta_ptr[6] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[6],16); beta_ptr[6] = vsetq_lane_s16(beta[51],beta_ptr[6],4);
beta_ptr[7] = (int16x8_t)vshrq_n_s64((int64x2_t)beta128[7],16); beta_ptr[7] = vsetq_lane_s16(beta[59],beta_ptr[7],4);
#endif
}
#if defined(__x86_64__) || defined(__i386__)
beta_ptr[0] = _mm_insert_epi16(beta_ptr[0],beta0_16,7);
beta_ptr[1] = _mm_insert_epi16(beta_ptr[1],beta1_16,7);
beta_ptr[2] = _mm_insert_epi16(beta_ptr[2],beta2_16,7);
@@ -413,10 +571,21 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
beta_ptr[5] = _mm_insert_epi16(beta_ptr[5],beta5_16,7);
beta_ptr[6] = _mm_insert_epi16(beta_ptr[6],beta6_16,7);
beta_ptr[7] = _mm_insert_epi16(beta_ptr[7],beta7_16,7);
#elif defined(__arm__)
beta_ptr[0] = vsetq_lane_s16(beta0_16,beta_ptr[0],7);
beta_ptr[1] = vsetq_lane_s16(beta1_16,beta_ptr[1],7);
beta_ptr[2] = vsetq_lane_s16(beta2_16,beta_ptr[2],7);
beta_ptr[3] = vsetq_lane_s16(beta3_16,beta_ptr[3],7);
beta_ptr[4] = vsetq_lane_s16(beta4_16,beta_ptr[4],7);
beta_ptr[5] = vsetq_lane_s16(beta5_16,beta_ptr[5],7);
beta_ptr[6] = vsetq_lane_s16(beta6_16,beta_ptr[6],7);
beta_ptr[7] = vsetq_lane_s16(beta7_16,beta_ptr[7],7);
#endif
int loopval=((rerun_flag==0)?0:((frame_length-L)>>3));
for (k=(frame_length>>3)-1; k>=loopval; k--) {
#if defined(__x86_64__) || defined(__i386__)
m11_128=((__m128i*)m_11)[k];
m10_128=((__m128i*)m_10)[k];
@@ -465,7 +634,55 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
beta_ptr[5] = _mm_subs_epi16(beta_ptr[5],beta_max);
beta_ptr[6] = _mm_subs_epi16(beta_ptr[6],beta_max);
beta_ptr[7] = _mm_subs_epi16(beta_ptr[7],beta_max);
#elif defined(__arm__)
m11_128=((int16x8_t*)m_11)[k];
m10_128=((int16x8_t*)m_10)[k];
m_b0 = vqaddq_s16(beta_ptr[4],m11_128); //m11
m_b1 = vqsubq_s16(beta_ptr[4],m11_128); //m00
m_b2 = vqsubq_s16(beta_ptr[5],m10_128); //m01
m_b3 = vqaddq_s16(beta_ptr[5],m10_128); //m10
m_b4 = vqaddq_s16(beta_ptr[6],m10_128); //m10
m_b5 = vqsubq_s16(beta_ptr[6],m10_128); //m01
m_b6 = vqsubq_s16(beta_ptr[7],m11_128); //m00
m_b7 = vqaddq_s16(beta_ptr[7],m11_128); //m11
new0 = vqsubq_s16(beta_ptr[0],m11_128); //m00
new1 = vqaddq_s16(beta_ptr[0],m11_128); //m11
new2 = vqaddq_s16(beta_ptr[1],m10_128); //m10
new3 = vqsubq_s16(beta_ptr[1],m10_128); //m01
new4 = vqsubq_s16(beta_ptr[2],m10_128); //m01
new5 = vqaddq_s16(beta_ptr[2],m10_128); //m10
new6 = vqaddq_s16(beta_ptr[3],m11_128); //m11
new7 = vqsubq_s16(beta_ptr[3],m11_128); //m00
beta_ptr-=8;
beta_ptr[0] = vmaxq_s16(m_b0,new0);
beta_ptr[1] = vmaxq_s16(m_b1,new1);
beta_ptr[2] = vmaxq_s16(m_b2,new2);
beta_ptr[3] = vmaxq_s16(m_b3,new3);
beta_ptr[4] = vmaxq_s16(m_b4,new4);
beta_ptr[5] = vmaxq_s16(m_b5,new5);
beta_ptr[6] = vmaxq_s16(m_b6,new6);
beta_ptr[7] = vmaxq_s16(m_b7,new7);
beta_max = vmaxq_s16(beta_ptr[0],beta_ptr[1]);
beta_max = vmaxq_s16(beta_max ,beta_ptr[2]);
beta_max = vmaxq_s16(beta_max ,beta_ptr[3]);
beta_max = vmaxq_s16(beta_max ,beta_ptr[4]);
beta_max = vmaxq_s16(beta_max ,beta_ptr[5]);
beta_max = vmaxq_s16(beta_max ,beta_ptr[6]);
beta_max = vmaxq_s16(beta_max ,beta_ptr[7]);
beta_ptr[0] = vqsubq_s16(beta_ptr[0],beta_max);
beta_ptr[1] = vqsubq_s16(beta_ptr[1],beta_max);
beta_ptr[2] = vqsubq_s16(beta_ptr[2],beta_max);
beta_ptr[3] = vqsubq_s16(beta_ptr[3],beta_max);
beta_ptr[4] = vqsubq_s16(beta_ptr[4],beta_max);
beta_ptr[5] = vqsubq_s16(beta_ptr[5],beta_max);
beta_ptr[6] = vqsubq_s16(beta_ptr[6],beta_max);
beta_ptr[7] = vqsubq_s16(beta_ptr[7],beta_max);
#endif
}
@@ -477,6 +694,7 @@ void compute_beta16(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sh
void compute_ext16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, llr_t* systematic,unsigned short frame_length)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *alpha128=(__m128i *)alpha;
__m128i *beta128=(__m128i *)beta;
__m128i *m11_128,*m10_128,*ext_128;
@@ -485,6 +703,17 @@ void compute_ext16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext,
__m128i m01_1,m01_2,m01_3,m01_4;
__m128i m10_1,m10_2,m10_3,m10_4;
__m128i m11_1,m11_2,m11_3,m11_4;
#elif defined(__arm__)
int16x8_t *alpha128=(int16x8_t *)alpha;
int16x8_t *beta128=(int16x8_t *)beta;
int16x8_t *m11_128,*m10_128,*ext_128;
int16x8_t *alpha_ptr,*beta_ptr;
int16x8_t m00_1,m00_2,m00_3,m00_4;
int16x8_t m01_1,m01_2,m01_3,m01_4;
int16x8_t m10_1,m10_2,m10_3,m10_4;
int16x8_t m11_1,m11_2,m11_3,m11_4;
#endif
int k;
//
@@ -501,9 +730,11 @@ void compute_ext16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext,
for (k=0; k<(frame_length>>3); k++) {
#if defined(__x86_64__) || defined(__i386__)
m11_128 = (__m128i*)&m_11[k<<3];
m10_128 = (__m128i*)&m_10[k<<3];
ext_128 = (__m128i*)&ext[k<<3];
/*
printf("EXT %03d\n",k);
print_shorts("a0:",&alpha_ptr[0]);
@@ -594,7 +825,54 @@ void compute_ext16(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext,
print_shorts("m01_1:",&m01_1);
print_shorts("syst:",systematic_128);
*/
#elif defined(__arm__)
m11_128 = (int16x8_t*)&m_11[k<<3];
m10_128 = (int16x8_t*)&m_10[k<<3];
ext_128 = (int16x8_t*)&ext[k<<3];
m00_4 = vqaddq_s16(alpha_ptr[7],beta_ptr[3]); //ALPHA_BETA_4m00;
m11_4 = vqaddq_s16(alpha_ptr[7],beta_ptr[7]); //ALPHA_BETA_4m11;
m00_3 = vqaddq_s16(alpha_ptr[6],beta_ptr[7]); //ALPHA_BETA_3m00;
m11_3 = vqaddq_s16(alpha_ptr[6],beta_ptr[3]); //ALPHA_BETA_3m11;
m00_2 = vqaddq_s16(alpha_ptr[1],beta_ptr[4]); //ALPHA_BETA_2m00;
m11_2 = vqaddq_s16(alpha_ptr[1],beta_ptr[0]); //ALPHA_BETA_2m11;
m11_1 = vqaddq_s16(alpha_ptr[0],beta_ptr[4]); //ALPHA_BETA_1m11;
m00_1 = vqaddq_s16(alpha_ptr[0],beta_ptr[0]); //ALPHA_BETA_1m00;
m01_4 = vqaddq_s16(alpha_ptr[5],beta_ptr[6]); //ALPHA_BETA_4m01;
m10_4 = vqaddq_s16(alpha_ptr[5],beta_ptr[2]); //ALPHA_BETA_4m10;
m01_3 = vqaddq_s16(alpha_ptr[4],beta_ptr[2]); //ALPHA_BETA_3m01;
m10_3 = vqaddq_s16(alpha_ptr[4],beta_ptr[6]); //ALPHA_BETA_3m10;
m01_2 = vqaddq_s16(alpha_ptr[3],beta_ptr[1]); //ALPHA_BETA_2m01;
m10_2 = vqaddq_s16(alpha_ptr[3],beta_ptr[5]); //ALPHA_BETA_2m10;
m10_1 = vqaddq_s16(alpha_ptr[2],beta_ptr[1]); //ALPHA_BETA_1m10;
m01_1 = vqaddq_s16(alpha_ptr[2],beta_ptr[5]); //ALPHA_BETA_1m01;
m01_1 = vmaxq_s16(m01_1,m01_2);
m01_1 = vmaxq_s16(m01_1,m01_3);
m01_1 = vmaxq_s16(m01_1,m01_4);
m00_1 = vmaxq_s16(m00_1,m00_2);
m00_1 = vmaxq_s16(m00_1,m00_3);
m00_1 = vmaxq_s16(m00_1,m00_4);
m10_1 = vmaxq_s16(m10_1,m10_2);
m10_1 = vmaxq_s16(m10_1,m10_3);
m10_1 = vmaxq_s16(m10_1,m10_4);
m11_1 = vmaxq_s16(m11_1,m11_2);
m11_1 = vmaxq_s16(m11_1,m11_3);
m11_1 = vmaxq_s16(m11_1,m11_4);
m01_1 = vqsubq_s16(m01_1,*m10_128);
m00_1 = vqsubq_s16(m00_1,*m11_128);
m10_1 = vqaddq_s16(m10_1,*m10_128);
m11_1 = vqaddq_s16(m11_1,*m11_128);
m01_1 = vmaxq_s16(m01_1,m00_1);
m10_1 = vmaxq_s16(m10_1,m11_1);
*ext_128 = vqsubq_s16(m10_1,m01_1);
#endif
alpha_ptr+=8;
beta_ptr+=8;
}
@@ -703,15 +981,23 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
int *pi2_p,*pi4_p,*pi5_p,*pi6_p;
llr_t *s,*s1,*s2,*yp1,*yp2,*yp;
__m128i *yp128;
unsigned int i,j,iind;//,pi;
unsigned char iteration_cnt=0;
unsigned int crc,oldcrc,crc_len;
uint8_t temp;
#if defined(__x86_64__) || defined(__i386__)
__m128i *yp128;
__m128i tmp, zeros=_mm_setzero_si128();
register __m128i tmpe;
#elif defined(__arm__)
int16x8_t *yp128;
// int16x8_t tmp128[(n+8)>>3];
int16x8_t tmp, zeros=vdupq_n_s16(0);
const uint16_t __attribute__ ((aligned (16))) _Powers[8]=
{ 1, 2, 4, 8, 16, 32, 64, 128};
uint16x8_t Powers= vld1q_u16(_Powers);
#endif
int offset8_flag=0;
if (crc_type > 3) {
@@ -749,7 +1035,11 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
crc_len=3;
}
#if defined(__x86_64__) || defined(__i386__)
yp128 = (__m128i*)y;
#elif defined(__arm__)
yp128 = (int16x8_t*)y;
#endif
@@ -767,7 +1057,7 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
j=pi2_p[0];
#if defined(__x86_64__) || defined(__i386__)
tmpe = _mm_load_si128(yp128);
s[j] = _mm_extract_epi16(tmpe,0);
@@ -826,6 +1116,46 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
yp2[j] = _mm_extract_epi16(tmpe,7);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
#elif defined(__arm__)
s[j] = vgetq_lane_s16(yp128[0],0);
yp1[j] = vgetq_lane_s16(yp128[0],1);
yp2[j] = vgetq_lane_s16(yp128[0],2);
j=pi2_p[1];
s[j] = vgetq_lane_s16(yp128[0],3);
yp1[j] = vgetq_lane_s16(yp128[0],4);
yp2[j] = vgetq_lane_s16(yp128[0],5);
j=pi2_p[2];
s[j] = vgetq_lane_s16(yp128[0],6);
yp1[j] = vgetq_lane_s16(yp128[0],7);
yp2[j] = vgetq_lane_s16(yp128[1],0);
j=pi2_p[3];
s[j] = vgetq_lane_s16(yp128[1],1);
yp1[j] = vgetq_lane_s16(yp128[1],2);
yp2[j] = vgetq_lane_s16(yp128[1],3);
j=pi2_p[4];
s[j] = vgetq_lane_s16(yp128[1],4);
yp1[j] = vgetq_lane_s16(yp128[1],5);
yp2[j] = vgetq_lane_s16(yp128[1],6);
j=pi2_p[5];
s[j] = vgetq_lane_s16(yp128[1],7);
yp1[j] = vgetq_lane_s16(yp128[2],0);
yp2[j] = vgetq_lane_s16(yp128[2],1);
j=pi2_p[6];
s[j] = vgetq_lane_s16(yp128[2],2);
yp1[j] = vgetq_lane_s16(yp128[2],3);
yp2[j] = vgetq_lane_s16(yp128[2],4);
j=pi2_p[7];
s[j] = vgetq_lane_s16(yp128[2],5);
yp1[j] = vgetq_lane_s16(yp128[2],6);
yp2[j] = vgetq_lane_s16(yp128[2],7);
#endif
yp128+=3;
}
@@ -879,7 +1209,7 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
pi4_p=pi4tab16[iind];
for (i=0; i<(n>>3); i++) { // steady-state portion
#if defined(__x86_64__) || defined(__i386__)
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],((llr_t*)ext)[*pi4_p++],0);
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],((llr_t*)ext)[*pi4_p++],1);
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],((llr_t*)ext)[*pi4_p++],2);
@@ -888,6 +1218,16 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],((llr_t*)ext)[*pi4_p++],5);
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],((llr_t*)ext)[*pi4_p++],6);
((__m128i *)systematic2)[i]=_mm_insert_epi16(((__m128i *)systematic2)[i],((llr_t*)ext)[*pi4_p++],7);
#elif defined(__arm__)
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],0);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],1);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],2);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],3);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],4);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],5);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],6);
((int16x8_t*)systematic2)[i]=vsetq_lane_s16(((llr_t*)ext)[*pi4_p++],((int16x8_t*)systematic2)[i],7);
#endif
}
stop_meas(intl1_stats);
@@ -901,6 +1241,7 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
pi5_p=pi5tab16[iind];
for (i=0; i<(n>>3); i++) {
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],0);
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],1);
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],2);
@@ -910,6 +1251,17 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],6);
tmp=_mm_insert_epi16(tmp,ext2[*pi5_p++],7);
((__m128i *)systematic1)[i] = _mm_adds_epi16(_mm_subs_epi16(tmp,((__m128i*)ext)[i]),((__m128i *)systematic0)[i]);
#elif defined(__arm__)
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,0);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,1);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,2);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,3);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,4);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,5);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,6);
tmp=vsetq_lane_s16(ext2[*pi5_p++],tmp,7);
((int16x8_t *)systematic1)[i] = vqaddq_s16(vqsubq_s16(tmp,((int16x8_t*)ext)[i]),((int16x8_t *)systematic0)[i]);
#endif
}
if (iteration_cnt>1) {
@@ -917,6 +1269,7 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
pi6_p=pi6tab16[iind];
for (i=0; i<(n>>3); i++) {
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],7);
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],6);
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],5);
@@ -927,7 +1280,24 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
tmp=_mm_insert_epi16(tmp, ((llr_t*)ext2)[*pi6_p++],0);
tmp=_mm_cmpgt_epi8(_mm_packs_epi16(tmp,zeros),zeros);
decoded_bytes[i]=(unsigned char)_mm_movemask_epi8(tmp);
#elif defined(__arm__)
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,7);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,6);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,5);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,4);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,3);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,2);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,1);
tmp=vsetq_lane_s16(ext2[*pi6_p++],tmp,0);
// This does:
// [1 2 4 8 16 32 64 128] .* I(ext_i > 0) = 2.^[b0 b1 b2 b3 b4 b5 b6 b7], where bi =I(ext_i > 0)
// [2^b0 + 2^b1 2^b2 + 2^b3 2^b4 + 2^b5 2^b6 + 2^b7]
// [2^b0 + 2^b1 + 2^b2 + 2^b3 2^b4 + 2^b5 + 2^b6 + 2^b7]
// Mask64 = 2^b0 + 2^b1 + 2^b2 + 2^b3 + 2^b4 + 2^b5 + 2^b6 + 2^b7
uint64x2_t Mask = vpaddlq_u32(vpaddlq_u16(vandq_u16(vcgtq_s16(tmp,zeros), Powers)));
uint64x1_t Mask64 = vget_high_u64(Mask)+vget_low_u64(Mask);
decoded_bytes[i] = (uint8_t)Mask64;
#endif
}
}
@@ -983,14 +1353,23 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
// do log_map from first parity bit
if (iteration_cnt < max_iterations) {
log_map16(systematic1,yparity1,m11,m10,alpha,beta,ext,n,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
#if defined(__x86_64__) || defined(__i386__)
__m128i* ext_128=(__m128i*) ext;
__m128i* s1_128=(__m128i*) systematic1;
__m128i* s0_128=(__m128i*) systematic0;
#elif defined(__arm__)
int16x8_t* ext_128=(int16x8_t*) ext;
int16x8_t* s1_128=(int16x8_t*) systematic1;
int16x8_t* s0_128=(int16x8_t*) systematic0;
#endif
int myloop=n>>3;
for (i=0; i<myloop; i++) {
#if defined(__x86_64__) || defined(__i386__)
*ext_128=_mm_adds_epi16(_mm_subs_epi16(*ext_128,*s1_128++),*s0_128++);
#elif defined(__arm__)
*ext_128=vqaddq_s16(vqsubq_s16(*ext_128,*s1_128++),*s0_128++);
#endif
ext_128++;
}
}
@@ -998,8 +1377,10 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
// printf("crc %x, oldcrc %x\n",crc,oldcrc);
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(iteration_cnt);
}
@@ -100,14 +100,13 @@ void compute_beta8(llr_t*alpha, llr_t* beta,llr_t* m11,llr_t* m10, unsigned shor
void compute_ext8(llr_t* alpha,llr_t* beta,llr_t* m11,llr_t* m10,llr_t* extrinsic, llr_t* ap, unsigned short frame_length);
void print_bytes(char *s, __m128i *x)
void print_bytes(char *s, int8_t *x)
{
int8_t *tempb = (int8_t *)x;
printf("%s : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",s,
tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7],
tempb[8],tempb[9],tempb[10],tempb[11],tempb[12],tempb[13],tempb[14],tempb[15]);
x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],
x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15]);
}
@@ -153,32 +152,47 @@ void compute_gamma8(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity,
unsigned short frame_length,unsigned char term_flag)
{
int k,K1;
#if defined(__x86_64__)||defined(__i386__)
__m128i *systematic128 = (__m128i *)systematic;
__m128i *y_parity128 = (__m128i *)y_parity;
__m128i *m10_128 = (__m128i *)m10;
__m128i *m11_128 = (__m128i *)m11;
#elif defined(__arm__)
int8x16_t *systematic128 = (int8x16_t *)systematic;
int8x16_t *y_parity128 = (int8x16_t *)y_parity;
int8x16_t *m10_128 = (int8x16_t *)m10;
int8x16_t *m11_128 = (int8x16_t *)m11;
#endif
#ifdef DEBUG_LOGMAP
msg("compute_gamma, %p,%p,%p,%p,framelength %d\n",m11,m10,systematic,y_parity,frame_length);
#endif
#if defined(__x86_64__) || defined(__i386__)
register __m128i sl,sh,ypl,yph; //K128=_mm_set1_epi8(-128);
#endif
K1 = (frame_length>>4);
for (k=0; k<K1; k++) {
#if defined(__x86_64__) || defined(__i386__)
sl = _mm_cvtepi8_epi16(systematic128[k]);
sh = _mm_cvtepi8_epi16(_mm_srli_si128(systematic128[k],8));
sh = _mm_cvtepi8_epi16(_mm_srli_si128(systematic128[k],8));
ypl = _mm_cvtepi8_epi16(y_parity128[k]);
yph = _mm_cvtepi8_epi16(_mm_srli_si128(y_parity128[k],8));
m11_128[k] = _mm_packs_epi16(_mm_srai_epi16(_mm_adds_epi16(sl,ypl),1),
_mm_srai_epi16(_mm_adds_epi16(sh,yph),1));
m10_128[k] = _mm_packs_epi16(_mm_srai_epi16(_mm_subs_epi16(sl,ypl),1),
_mm_srai_epi16(_mm_subs_epi16(sh,yph),1));
#elif defined(__arm__)
m11_128[k] = vhaddq_s8(systematic128[k],y_parity128[k]);
m10_128[k] = vhsubq_s8(systematic128[k],y_parity128[k]);
#endif
}
// Termination
#if defined(__x86_64__) || defined(__i386__)
sl = _mm_cvtepi8_epi16(systematic128[k+term_flag]);
sh = _mm_cvtepi8_epi16(_mm_srli_si128(systematic128[k],8));
ypl = _mm_cvtepi8_epi16(y_parity128[k+term_flag]);
@@ -187,7 +201,10 @@ void compute_gamma8(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity,
_mm_srai_epi16(_mm_adds_epi16(sh,yph),1));
m10_128[k] = _mm_packs_epi16(_mm_srai_epi16(_mm_subs_epi16(sl,ypl),1),
_mm_srai_epi16(_mm_subs_epi16(sh,yph),1));
#elif defined(__arm__)
m11_128[k] = vhaddq_s8(systematic128[k+term_flag],y_parity128[k]);
m10_128[k] = vhsubq_s8(systematic128[k+term_flag],y_parity128[k]);
#endif
}
@@ -196,14 +213,24 @@ void compute_gamma8(llr_t* m11,llr_t* m10,llr_t* systematic,channel_t* y_parity,
void compute_alpha8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned short frame_length,unsigned char F)
{
int k,loopval,rerun_flag;
#if defined(__x86_64__) || defined(__i386__)
__m128i *alpha128=(__m128i *)alpha,*alpha_ptr;
__m128i *m11p,*m10p;
__m128i m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
__m128i new0,new1,new2,new3,new4,new5,new6,new7;
__m128i alpha_max;
#elif defined(__arm__)
int8x16_t *alpha128=(int8x16_t *)alpha,*alpha_ptr;
int8x16_t *m11p,*m10p;
int8x16_t m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
int8x16_t new0,new1,new2,new3,new4,new5,new6,new7;
int8x16_t alpha_max;
#endif
// Set initial state: first colum is known
// the other columns are unknown, so all states are set to same value
#if defined(__x86_64__) || defined(__i386__)
alpha128[0] = _mm_set_epi8(-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,0);
alpha128[1] = _mm_set_epi8(-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2);
alpha128[2] = _mm_set_epi8(-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2);
@@ -212,10 +239,10 @@ void compute_alpha8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned sh
alpha128[5] = _mm_set_epi8(-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2);
alpha128[6] = _mm_set_epi8(-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2);
alpha128[7] = _mm_set_epi8(-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2,-MAX8/2);
for (loopval=frame_length>>4, rerun_flag=0; rerun_flag<2; loopval=L, rerun_flag++) {
alpha_ptr = &alpha128[0];
m11p = (__m128i*)m_11;
m10p = (__m128i*)m_10;
@@ -289,6 +316,95 @@ void compute_alpha8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,unsigned sh
alpha[112] = -MAX8/2;
}
#elif defined(__arm__)
alpha128[0] = vdupq_n_s8(-MAX8/2);
alpha128[0] = vsetq_lane_s8(0,alpha128[0],0);
alpha128[1] = vdupq_n_s8(-MAX8/2);
alpha128[2] = vdupq_n_s8(-MAX8/2);
alpha128[3] = vdupq_n_s8(-MAX8/2);
alpha128[4] = vdupq_n_s8(-MAX8/2);
alpha128[5] = vdupq_n_s8(-MAX8/2);
alpha128[6] = vdupq_n_s8(-MAX8/2);
alpha128[7] = vdupq_n_s8(-MAX8/2);
for (loopval=frame_length>>4, rerun_flag=0; rerun_flag<2; loopval=L, rerun_flag++) {
alpha_ptr = &alpha128[0];
m11p = (int8x16_t*)m_11;
m10p = (int8x16_t*)m_10;
for (k=0; k<loopval; k++) {
m_b0 = vqaddq_s8(alpha_ptr[1],*m11p); // m11
m_b4 = vqsubq_s8(alpha_ptr[1],*m11p); // m00=-m11
m_b1 = vqsubq_s8(alpha_ptr[3],*m10p); // m01=-m10
m_b5 = vqaddq_s8(alpha_ptr[3],*m10p); // m10
m_b2 = vqaddq_s8(alpha_ptr[5],*m10p); // m10
m_b6 = vqsubq_s8(alpha_ptr[5],*m10p); // m01=-m10
m_b3 = vqsubq_s8(alpha_ptr[7],*m11p); // m00=-m11
m_b7 = vqaddq_s8(alpha_ptr[7],*m11p); // m11
new0 = vqsubq_s8(alpha_ptr[0],*m11p); // m00=-m11
new4 = vqaddq_s8(alpha_ptr[0],*m11p); // m11
new1 = vqaddq_s8(alpha_ptr[2],*m10p); // m10
new5 = vqsubq_s8(alpha_ptr[2],*m10p); // m01=-m10
new2 = vqsubq_s8(alpha_ptr[4],*m10p); // m01=-m10
new6 = vqaddq_s8(alpha_ptr[4],*m10p); // m10
new3 = vqaddq_s8(alpha_ptr[6],*m11p); // m11
new7 = vqsubq_s8(alpha_ptr[6],*m11p); // m00=-m11
alpha_ptr += 8;
m11p++;
m10p++;
alpha_ptr[0] = vmaxq_s8(m_b0,new0);
alpha_ptr[1] = vmaxq_s8(m_b1,new1);
alpha_ptr[2] = vmaxq_s8(m_b2,new2);
alpha_ptr[3] = vmaxq_s8(m_b3,new3);
alpha_ptr[4] = vmaxq_s8(m_b4,new4);
alpha_ptr[5] = vmaxq_s8(m_b5,new5);
alpha_ptr[6] = vmaxq_s8(m_b6,new6);
alpha_ptr[7] = vmaxq_s8(m_b7,new7);
// compute and subtract maxima
alpha_max = vmaxq_s8(alpha_ptr[0],alpha_ptr[1]);
alpha_max = vmaxq_s8(alpha_max,alpha_ptr[2]);
alpha_max = vmaxq_s8(alpha_max,alpha_ptr[3]);
alpha_max = vmaxq_s8(alpha_max,alpha_ptr[4]);
alpha_max = vmaxq_s8(alpha_max,alpha_ptr[5]);
alpha_max = vmaxq_s8(alpha_max,alpha_ptr[6]);
alpha_max = vmaxq_s8(alpha_max,alpha_ptr[7]);
alpha_ptr[0] = vqsubq_s8(alpha_ptr[0],alpha_max);
alpha_ptr[1] = vqsubq_s8(alpha_ptr[1],alpha_max);
alpha_ptr[2] = vqsubq_s8(alpha_ptr[2],alpha_max);
alpha_ptr[3] = vqsubq_s8(alpha_ptr[3],alpha_max);
alpha_ptr[4] = vqsubq_s8(alpha_ptr[4],alpha_max);
alpha_ptr[5] = vqsubq_s8(alpha_ptr[5],alpha_max);
alpha_ptr[6] = vqsubq_s8(alpha_ptr[6],alpha_max);
alpha_ptr[7] = vqsubq_s8(alpha_ptr[7],alpha_max);
}
// Set intial state for next iteration from the last state
// as a column end states are the first states of the next column
int K1= frame_length>>1;
alpha128[0] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[K1],8); alpha128[0] = vsetq_lane_s8(alpha[8],alpha128[0],7);
alpha128[1] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[1+K1],8); alpha128[1] = vsetq_lane_s8(alpha[24],alpha128[0],7);
alpha128[2] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[2+K1],8); alpha128[2] = vsetq_lane_s8(alpha[40],alpha128[0],7);
alpha128[3] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[3+K1],8); alpha128[3] = vsetq_lane_s8(alpha[56],alpha128[0],7);
alpha128[4] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[4+K1],8); alpha128[4] = vsetq_lane_s8(alpha[72],alpha128[0],7);
alpha128[5] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[5+K1],8); alpha128[5] = vsetq_lane_s8(alpha[88],alpha128[0],7);
alpha128[6] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[6+K1],8); alpha128[6] = vsetq_lane_s8(alpha[104],alpha128[0],7);
alpha128[7] = (int8x16_t)vshlq_n_s64((int64x2_t)alpha128[7+K1],8); alpha128[7] = vsetq_lane_s8(alpha[120],alpha128[0],7);
alpha[16] = -MAX8/2;
alpha[32] = -MAX8/2;
alpha[48] = -MAX8/2;
alpha[64] = -MAX8/2;
alpha[80] = -MAX8/2;
alpha[96] = -MAX8/2;
alpha[112] = -MAX8/2;
}
#endif
}
@@ -297,13 +413,21 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
{
int k,rerun_flag, loopval;
#if defined(__x86_64__) || defined(__i386__)
__m128i m11_128,m10_128;
__m128i m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
__m128i new0,new1,new2,new3,new4,new5,new6,new7;
__m128i *beta128,*alpha128,*beta_ptr;
__m128i beta_max;
#elif defined(__arm__)
int8x16_t m11_128,m10_128;
int8x16_t m_b0,m_b1,m_b2,m_b3,m_b4,m_b5,m_b6,m_b7;
int8x16_t new0,new1,new2,new3,new4,new5,new6,new7;
int8x16_t *beta128,*alpha128,*beta_ptr;
int8x16_t beta_max;
#endif
llr_t beta0,beta1;
llr_t beta2,beta3,beta4,beta5,beta6,beta7;
@@ -371,8 +495,14 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
// we are supposed to run compute_alpha just before compute_beta
// so the initial states of backward computation can be set from last value of alpha states (forward computation)
#if defined(__x86_64__) || defined(__i386__)
beta_ptr = (__m128i*)&beta[frame_length<<3];
alpha128 = (__m128i*)&alpha[0];
#elif defined(__arm__)
beta_ptr = (int8x16_t*)&beta[frame_length<<3];
alpha128 = (int8x16_t*)&alpha[0];
#endif
beta_ptr[0] = alpha128[(frame_length>>1)];
beta_ptr[1] = alpha128[1+(frame_length>>1)];
beta_ptr[2] = alpha128[2+(frame_length>>1)];
@@ -391,6 +521,7 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
// workaround: init with 0
beta0 = beta1 = beta2 = beta3 = beta4 = beta5 = beta6 = beta7 = 0;
#if defined(__x86_64__) || defined(__i386__)
beta_ptr[0] = _mm_insert_epi8(beta_ptr[0],beta0,15);
beta_ptr[1] = _mm_insert_epi8(beta_ptr[1],beta1,15);
beta_ptr[2] = _mm_insert_epi8(beta_ptr[2],beta2,15);
@@ -399,12 +530,27 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
beta_ptr[5] = _mm_insert_epi8(beta_ptr[5],beta5,15);
beta_ptr[6] = _mm_insert_epi8(beta_ptr[6],beta6,15);
beta_ptr[7] = _mm_insert_epi8(beta_ptr[7],beta7,15);
#elif defined(__arm__)
beta_ptr[0] = vsetq_lane_s8(beta0,beta_ptr[0],15);
beta_ptr[1] = vsetq_lane_s8(beta1,beta_ptr[1],15);
beta_ptr[2] = vsetq_lane_s8(beta2,beta_ptr[2],15);
beta_ptr[3] = vsetq_lane_s8(beta3,beta_ptr[3],15);
beta_ptr[4] = vsetq_lane_s8(beta4,beta_ptr[4],15);
beta_ptr[5] = vsetq_lane_s8(beta5,beta_ptr[5],15);
beta_ptr[6] = vsetq_lane_s8(beta6,beta_ptr[6],15);
beta_ptr[7] = vsetq_lane_s8(beta7,beta_ptr[7],15);
#endif
}
for (k=(frame_length>>4)-1, beta_ptr = (__m128i*)&beta[frame_length<<3] ;
#if defined(__x86_64__) || defined(__i386__)
beta_ptr = (__m128i*)&beta[frame_length<<3];
#elif defined(__arm__)
beta_ptr = (int8x16_t*)&beta[frame_length<<3];
#endif
for (k=(frame_length>>4)-1;
k>=loopval;
k--) {
#if defined(__x86_64__) || defined(__i386__)
m11_128=((__m128i*)m_11)[k];
m10_128=((__m128i*)m_10)[k];
m_b0 = _mm_adds_epi8(beta_ptr[4],m11_128); //m11
@@ -452,12 +598,62 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
beta_ptr[5] = _mm_subs_epi8(beta_ptr[5],beta_max);
beta_ptr[6] = _mm_subs_epi8(beta_ptr[6],beta_max);
beta_ptr[7] = _mm_subs_epi8(beta_ptr[7],beta_max);
#elif defined(__arm__)
m11_128=((int8x16_t*)m_11)[k];
m10_128=((int8x16_t*)m_10)[k];
m_b0 = vqaddq_s8(beta_ptr[4],m11_128); //m11
m_b1 = vqsubq_s8(beta_ptr[4],m11_128); //m00
m_b2 = vqsubq_s8(beta_ptr[5],m10_128); //m01
m_b3 = vqaddq_s8(beta_ptr[5],m10_128); //m10
m_b4 = vqaddq_s8(beta_ptr[6],m10_128); //m10
m_b5 = vqsubq_s8(beta_ptr[6],m10_128); //m01
m_b6 = vqsubq_s8(beta_ptr[7],m11_128); //m00
m_b7 = vqaddq_s8(beta_ptr[7],m11_128); //m11
new0 = vqsubq_s8(beta_ptr[0],m11_128); //m00
new1 = vqaddq_s8(beta_ptr[0],m11_128); //m11
new2 = vqaddq_s8(beta_ptr[1],m10_128); //m10
new3 = vqsubq_s8(beta_ptr[1],m10_128); //m01
new4 = vqsubq_s8(beta_ptr[2],m10_128); //m01
new5 = vqaddq_s8(beta_ptr[2],m10_128); //m10
new6 = vqaddq_s8(beta_ptr[3],m11_128); //m11
new7 = vqsubq_s8(beta_ptr[3],m11_128); //m00
beta_ptr-=8;
beta_ptr[0] = vmaxq_s8(m_b0,new0);
beta_ptr[1] = vmaxq_s8(m_b1,new1);
beta_ptr[2] = vmaxq_s8(m_b2,new2);
beta_ptr[3] = vmaxq_s8(m_b3,new3);
beta_ptr[4] = vmaxq_s8(m_b4,new4);
beta_ptr[5] = vmaxq_s8(m_b5,new5);
beta_ptr[6] = vmaxq_s8(m_b6,new6);
beta_ptr[7] = vmaxq_s8(m_b7,new7);
beta_max = vmaxq_s8(beta_ptr[0],beta_ptr[1]);
beta_max = vmaxq_s8(beta_max ,beta_ptr[2]);
beta_max = vmaxq_s8(beta_max ,beta_ptr[3]);
beta_max = vmaxq_s8(beta_max ,beta_ptr[4]);
beta_max = vmaxq_s8(beta_max ,beta_ptr[5]);
beta_max = vmaxq_s8(beta_max ,beta_ptr[6]);
beta_max = vmaxq_s8(beta_max ,beta_ptr[7]);
beta_ptr[0] = vqsubq_s8(beta_ptr[0],beta_max);
beta_ptr[1] = vqsubq_s8(beta_ptr[1],beta_max);
beta_ptr[2] = vqsubq_s8(beta_ptr[2],beta_max);
beta_ptr[3] = vqsubq_s8(beta_ptr[3],beta_max);
beta_ptr[4] = vqsubq_s8(beta_ptr[4],beta_max);
beta_ptr[5] = vqsubq_s8(beta_ptr[5],beta_max);
beta_ptr[6] = vqsubq_s8(beta_ptr[6],beta_max);
beta_ptr[7] = vqsubq_s8(beta_ptr[7],beta_max);
#endif
}
// Set intial state for next iteration from the last state
// as column last states are the first states of the next column
// The initial state of colum 0 is coming from tail bits (to be computed)
// The initial state of column 0 is coming from tail bits (to be computed)
#if defined(__x86_64__) || defined(__i386__)
beta128 = (__m128i*)&beta[0];
beta_ptr = (__m128i*)&beta[frame_length<<3];
beta_ptr[0] = _mm_srli_si128(beta128[0],1);
@@ -468,12 +664,25 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
beta_ptr[5] = _mm_srli_si128(beta128[5],1);
beta_ptr[6] = _mm_srli_si128(beta128[6],1);
beta_ptr[7] = _mm_srli_si128(beta128[7],1);
#elif defined(__arm__)
beta128 = (int8x16_t*)&beta[0];
beta_ptr = (int8x16_t*)&beta[frame_length<<3];
beta_ptr[0] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[0],8); beta_ptr[0] = vsetq_lane_s8(beta[7],beta_ptr[0],8);
beta_ptr[1] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[1],8); beta_ptr[1] = vsetq_lane_s8(beta[23],beta_ptr[1],8);
beta_ptr[2] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[2],8); beta_ptr[2] = vsetq_lane_s8(beta[39],beta_ptr[2],8);
beta_ptr[3] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[3],8); beta_ptr[3] = vsetq_lane_s8(beta[55],beta_ptr[3],8);
beta_ptr[4] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[4],8); beta_ptr[4] = vsetq_lane_s8(beta[71],beta_ptr[4],8);
beta_ptr[5] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[5],8); beta_ptr[5] = vsetq_lane_s8(beta[87],beta_ptr[5],8);
beta_ptr[6] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[6],8); beta_ptr[6] = vsetq_lane_s8(beta[103],beta_ptr[6],8);
beta_ptr[7] = (int8x16_t)vshrq_n_s64((int64x2_t)beta128[7],8); beta_ptr[7] = vsetq_lane_s8(beta[119],beta_ptr[7],8);
#endif
}
}
void compute_ext8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, llr_t* systematic,unsigned short frame_length)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *alpha128=(__m128i *)alpha;
__m128i *beta128=(__m128i *)beta;
__m128i *m11_128,*m10_128,*ext_128;
@@ -482,6 +691,16 @@ void compute_ext8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, l
__m128i m01_1,m01_2,m01_3,m01_4;
__m128i m10_1,m10_2,m10_3,m10_4;
__m128i m11_1,m11_2,m11_3,m11_4;
#elif defined(__arm__)
int8x16_t *alpha128=(int8x16_t *)alpha;
int8x16_t *beta128=(int8x16_t *)beta;
int8x16_t *m11_128,*m10_128,*ext_128;
int8x16_t *alpha_ptr,*beta_ptr;
int8x16_t m00_1,m00_2,m00_3,m00_4;
int8x16_t m01_1,m01_2,m01_3,m01_4;
int8x16_t m10_1,m10_2,m10_3,m10_4;
int8x16_t m11_1,m11_2,m11_3,m11_4;
#endif
int k;
//
@@ -498,6 +717,8 @@ void compute_ext8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, l
for (k=0; k<(frame_length>>4); k++) {
#if defined(__x86_64__) || defined(__i386__)
m11_128 = (__m128i*)&m_11[k<<4];
m10_128 = (__m128i*)&m_10[k<<4];
ext_128 = (__m128i*)&ext[k<<4];
@@ -547,6 +768,59 @@ void compute_ext8(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, l
alpha_ptr+=8;
beta_ptr+=8;
#elif defined(__arm__)
m11_128 = (int8x16_t*)&m_11[k<<4];
m10_128 = (int8x16_t*)&m_10[k<<4];
ext_128 = (int8x16_t*)&ext[k<<4];
m00_4 = vqaddq_s8(alpha_ptr[7],beta_ptr[3]); //ALPHA_BETA_4m00;
m11_4 = vqaddq_s8(alpha_ptr[7],beta_ptr[7]); //ALPHA_BETA_4m11;
m00_3 = vqaddq_s8(alpha_ptr[6],beta_ptr[7]); //ALPHA_BETA_3m00;
m11_3 = vqaddq_s8(alpha_ptr[6],beta_ptr[3]); //ALPHA_BETA_3m11;
m00_2 = vqaddq_s8(alpha_ptr[1],beta_ptr[4]); //ALPHA_BETA_2m00;
m11_2 = vqaddq_s8(alpha_ptr[1],beta_ptr[0]); //ALPHA_BETA_2m11;
m11_1 = vqaddq_s8(alpha_ptr[0],beta_ptr[4]); //ALPHA_BETA_1m11;
m00_1 = vqaddq_s8(alpha_ptr[0],beta_ptr[0]); //ALPHA_BETA_1m00;
m01_4 = vqaddq_s8(alpha_ptr[5],beta_ptr[6]); //ALPHA_BETA_4m01;
m10_4 = vqaddq_s8(alpha_ptr[5],beta_ptr[2]); //ALPHA_BETA_4m10;
m01_3 = vqaddq_s8(alpha_ptr[4],beta_ptr[2]); //ALPHA_BETA_3m01;
m10_3 = vqaddq_s8(alpha_ptr[4],beta_ptr[6]); //ALPHA_BETA_3m10;
m01_2 = vqaddq_s8(alpha_ptr[3],beta_ptr[1]); //ALPHA_BETA_2m01;
m10_2 = vqaddq_s8(alpha_ptr[3],beta_ptr[5]); //ALPHA_BETA_2m10;
m10_1 = vqaddq_s8(alpha_ptr[2],beta_ptr[1]); //ALPHA_BETA_1m10;
m01_1 = vqaddq_s8(alpha_ptr[2],beta_ptr[5]); //ALPHA_BETA_1m01;
m01_1 = vmaxq_s8(m01_1,m01_2);
m01_1 = vmaxq_s8(m01_1,m01_3);
m01_1 = vmaxq_s8(m01_1,m01_4);
m00_1 = vmaxq_s8(m00_1,m00_2);
m00_1 = vmaxq_s8(m00_1,m00_3);
m00_1 = vmaxq_s8(m00_1,m00_4);
m10_1 = vmaxq_s8(m10_1,m10_2);
m10_1 = vmaxq_s8(m10_1,m10_3);
m10_1 = vmaxq_s8(m10_1,m10_4);
m11_1 = vmaxq_s8(m11_1,m11_2);
m11_1 = vmaxq_s8(m11_1,m11_3);
m11_1 = vmaxq_s8(m11_1,m11_4);
m01_1 = vqsubq_s8(m01_1,*m10_128);
m00_1 = vqsubq_s8(m00_1,*m11_128);
m10_1 = vqaddq_s8(m10_1,*m10_128);
m11_1 = vqaddq_s8(m11_1,*m11_128);
m01_1 = vmaxq_s8(m01_1,m00_1);
m10_1 = vmaxq_s8(m10_1,m11_1);
*ext_128 = vqsubq_s8(m10_1,m01_1);
alpha_ptr+=8;
beta_ptr+=8;
#endif
}
@@ -661,14 +935,25 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
// int *pi2_p,*pi4_p,*pi5_p,*pi6_p;
int *pi4_p,*pi5_p,*pi6_p;
llr_t *s,*s1,*s2,*yp1,*yp2,*yp;
__m128i *yp128;
unsigned int i,j,iind;//,pi;
unsigned char iteration_cnt=0;
unsigned int crc,oldcrc,crc_len;
uint8_t temp;
#if defined(__x86_64__) || defined(__i386__)
__m128i *yp128;
__m128i tmp128[(n+8)>>3];
__m128i tmp, zeros=_mm_setzero_si128();
#elif defined(__arm__)
int8x16_t *yp128;
int8x16_t tmp128[(n+8)>>3];
int8x16_t tmp, zeros=vdupq_n_s8(0);
const uint8_t __attribute__ ((aligned (16))) _Powers[16]=
{ 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 };
// Set the powers of 2 (do it once for all, if applicable)
uint8x16_t Powers= vld1q_u8(_Powers);
#endif
int offset8_flag=0;
@@ -713,6 +998,8 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
crc_len=3;
}
#if defined(__x86_64__) || defined(__i386__)
__m128i avg=_mm_set1_epi32(0);
for (i=0; i<(3*(n>>4))+1; i++) {
@@ -721,7 +1008,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
avg=_mm_add_epi32(_mm_cvtepi16_epi32(tmp),avg);
}
int round_avg=(_mm_extract_epi32(avg,0)+_mm_extract_epi32(avg,1)+_mm_extract_epi32(avg,2)+_mm_extract_epi32(avg,3))/(n*3);
int32_t round_avg=(_mm_extract_epi32(avg,0)+_mm_extract_epi32(avg,1)+_mm_extract_epi32(avg,2)+_mm_extract_epi32(avg,3))/(n*3);
//printf("avg input turbo: %d sum %d taille bloc %d\n",round_avg,round_sum,n);
@@ -734,12 +1021,44 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
else if (round_avg < 64 )
for (i=0,j=0; i<(3*(n2>>4))+1; i++,j+=2)
((__m128i *)y8)[i] = _mm_packs_epi16(_mm_srai_epi16(((__m128i *)y)[j],2),_mm_srai_epi16(((__m128i *)y)[j+1],2));
else
else if (round_avg < 128)
for (i=0,j=0; i<(3*(n2>>4))+1; i++,j+=2)
((__m128i *)y8)[i] = _mm_packs_epi16(_mm_srai_epi16(((__m128i *)y)[j],3),_mm_srai_epi16(((__m128i *)y)[j+1],3));
else
for (i=0,j=0; i<(3*(n2>>4))+1; i++,j+=2)
((__m128i *)y8)[i] = _mm_packs_epi16(_mm_srai_epi16(((__m128i *)y)[j],3),_mm_srai_epi16(((__m128i *)y)[j+1],4));
yp128 = (__m128i*)y8;
#elif defined(__arm__)
int32x4_t avg=vdupq_n_s32(0);
for (i=0; i<(3*(n>>4))+1; i++) {
int16x8_t tmp=vabsq_s16(((int16x8_t*)y)[i]);
avg = vqaddq_s32(avg,vaddl_s16(((int16x4_t*)&tmp)[0],((int16x4_t*)&tmp)[1]));
}
int32_t round_avg=(vgetq_lane_s32(avg,0)+vgetq_lane_s32(avg,1)+vgetq_lane_s32(avg,2)+vgetq_lane_s32(avg,3))/(n*3);
//printf("avg input turbo: %d sum %d taille bloc %d\n",round_avg,round_sum,n);
if (round_avg < 16 )
for (i=0,j=0; i<(3*(n2>>3))+1; i++,j+=2)
((int8x8_t *)y8)[i] = vqmovn_s16(((int16x8_t *)y)[j]);
else if (round_avg < 32)
for (i=0,j=0; i<(3*(n2>>3))+1; i++,j+=2)
((int8x8_t *)y8)[i] = vqmovn_s16(vshrq_n_s16(((int16x8_t *)y)[j],1));
else if (round_avg < 64 )
for (i=0,j=0; i<(3*(n2>>3))+1; i++,j+=2)
((int8x8_t *)y8)[i] = vqmovn_s16(vshrq_n_s16(((int16x8_t *)y)[j],2));
else
for (i=0,j=0; i<(3*(n2>>3))+1; i++,j+=2)
((int8x8_t *)y8)[i] = vqmovn_s16(vshrq_n_s16(((int16x8_t *)y)[j],3));
yp128 = (int8x16_t*)y8;
#endif
s = systematic0;
s1 = systematic1;
@@ -764,101 +1083,198 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
pi2_p = &pi2tab8[iind][i];
j=pi2_p[0];
#if defined(__x86_64__) || defined(__i386__)
s[j] = _mm_extract_epi8(yp128[0],0);
yp1[j] = _mm_extract_epi8(yp128[0],1);
yp2[j] = _mm_extract_epi8(yp128[0],2);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[1];
s[j] = _mm_extract_epi8(yp128[0],3);
yp1[j] = _mm_extract_epi8(yp128[0],4);
yp2[j] = _mm_extract_epi8(yp128[0],5);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[2];
s[j] = _mm_extract_epi8(yp128[0],6);
yp1[j] = _mm_extract_epi8(yp128[0],7);
yp2[j] = _mm_extract_epi8(yp128[0],8);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[3];
s[j] = _mm_extract_epi8(yp128[0],9);
yp1[j] = _mm_extract_epi8(yp128[0],10);
yp2[j] = _mm_extract_epi8(yp128[0],11);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[4];
s[j] = _mm_extract_epi8(yp128[0],12);
yp1[j] = _mm_extract_epi8(yp128[0],13);
yp2[j] = _mm_extract_epi8(yp128[0],14);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[5];
s[j] = _mm_extract_epi8(yp128[0],15);
yp1[j] = _mm_extract_epi8(yp128[1],0);
yp2[j] = _mm_extract_epi8(yp128[1],1);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[6];
s[j] = _mm_extract_epi8(yp128[1],2);
yp1[j] = _mm_extract_epi8(yp128[1],3);
yp2[j] = _mm_extract_epi8(yp128[1],4);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[7];
s[j] = _mm_extract_epi8(yp128[1],5);
yp1[j] = _mm_extract_epi8(yp128[1],6);
yp2[j] = _mm_extract_epi8(yp128[1],7);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[8];
s[j] = _mm_extract_epi8(yp128[1],8);
yp1[j] = _mm_extract_epi8(yp128[1],9);
yp2[j] = _mm_extract_epi8(yp128[1],10);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[9];
s[j] = _mm_extract_epi8(yp128[1],11);
yp1[j] = _mm_extract_epi8(yp128[1],12);
yp2[j] = _mm_extract_epi8(yp128[1],13);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[10];
s[j] = _mm_extract_epi8(yp128[1],14);
yp1[j] = _mm_extract_epi8(yp128[1],15);
yp2[j] = _mm_extract_epi8(yp128[2],0);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[11];
s[j] = _mm_extract_epi8(yp128[2],1);
yp1[j] = _mm_extract_epi8(yp128[2],2);
yp2[j] = _mm_extract_epi8(yp128[2],3);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[12];
s[j] = _mm_extract_epi8(yp128[2],4);
yp1[j] = _mm_extract_epi8(yp128[2],5);
yp2[j] = _mm_extract_epi8(yp128[2],6);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[13];
s[j] = _mm_extract_epi8(yp128[2],7);
yp1[j] = _mm_extract_epi8(yp128[2],8);
yp2[j] = _mm_extract_epi8(yp128[2],9);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[14];
s[j] = _mm_extract_epi8(yp128[2],10);
yp1[j] = _mm_extract_epi8(yp128[2],11);
yp2[j] = _mm_extract_epi8(yp128[2],12);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
j=pi2_p[15];
s[j] = _mm_extract_epi8(yp128[2],13);
yp1[j] = _mm_extract_epi8(yp128[2],14);
yp2[j] = _mm_extract_epi8(yp128[2],15);
// printf("init: j %d, s[j] %d yp1[j] %d yp2[j] %d\n",j,s[j],yp1[j],yp2[j]);
#elif defined(__arm__)
s[j] = vgetq_lane_s8(yp128[0],0);
yp1[j] = vgetq_lane_s8(yp128[0],1);
yp2[j] = vgetq_lane_s8(yp128[0],2);
j=pi2_p[1];
s[j] = vgetq_lane_s8(yp128[0],3);
yp1[j] = vgetq_lane_s8(yp128[0],4);
yp2[j] = vgetq_lane_s8(yp128[0],5);
j=pi2_p[2];
s[j] = vgetq_lane_s8(yp128[0],6);
yp1[j] = vgetq_lane_s8(yp128[0],7);
yp2[j] = vgetq_lane_s8(yp128[0],8);
j=pi2_p[3];
s[j] = vgetq_lane_s8(yp128[0],9);
yp1[j] = vgetq_lane_s8(yp128[0],10);
yp2[j] = vgetq_lane_s8(yp128[0],11);
j=pi2_p[4];
s[j] = vgetq_lane_s8(yp128[0],12);
yp1[j] = vgetq_lane_s8(yp128[0],13);
yp2[j] = vgetq_lane_s8(yp128[0],14);
j=pi2_p[5];
s[j] = vgetq_lane_s8(yp128[0],15);
yp1[j] = vgetq_lane_s8(yp128[1],0);
yp2[j] = vgetq_lane_s8(yp128[1],1);
j=pi2_p[6];
s[j] = vgetq_lane_s8(yp128[1],2);
yp1[j] = vgetq_lane_s8(yp128[1],3);
yp2[j] = vgetq_lane_s8(yp128[1],4);
j=pi2_p[7];
s[j] = vgetq_lane_s8(yp128[1],5);
yp1[j] = vgetq_lane_s8(yp128[1],6);
yp2[j] = vgetq_lane_s8(yp128[1],7);
j=pi2_p[8];
s[j] = vgetq_lane_s8(yp128[1],8);
yp1[j] = vgetq_lane_s8(yp128[1],9);
yp2[j] = vgetq_lane_s8(yp128[1],10);
j=pi2_p[9];
s[j] = vgetq_lane_s8(yp128[1],11);
yp1[j] = vgetq_lane_s8(yp128[1],12);
yp2[j] = vgetq_lane_s8(yp128[1],13);
j=pi2_p[10];
s[j] = vgetq_lane_s8(yp128[1],14);
yp1[j] = vgetq_lane_s8(yp128[1],15);
yp2[j] = vgetq_lane_s8(yp128[2],0);
j=pi2_p[11];
s[j] = vgetq_lane_s8(yp128[2],1);
yp1[j] = vgetq_lane_s8(yp128[2],2);
yp2[j] = vgetq_lane_s8(yp128[2],3);
j=pi2_p[12];
s[j] = vgetq_lane_s8(yp128[2],4);
yp1[j] = vgetq_lane_s8(yp128[2],5);
yp2[j] = vgetq_lane_s8(yp128[2],6);
j=pi2_p[13];
s[j] = vgetq_lane_s8(yp128[2],7);
yp1[j] = vgetq_lane_s8(yp128[2],8);
yp2[j] = vgetq_lane_s8(yp128[2],9);
j=pi2_p[14];
s[j] = vgetq_lane_s8(yp128[2],10);
yp1[j] = vgetq_lane_s8(yp128[2],11);
yp2[j] = vgetq_lane_s8(yp128[2],12);
j=pi2_p[15];
s[j] = vgetq_lane_s8(yp128[2],13);
yp1[j] = vgetq_lane_s8(yp128[2],14);
yp2[j] = vgetq_lane_s8(yp128[2],15);
#endif
yp128+=3;
}
@@ -918,13 +1334,14 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
while (iteration_cnt++ < max_iterations) {
#ifdef DEBUG_LOGMAP
printf("\n*******************ITERATION %d (n %d), ext %p\n\n",iteration_cnt,n,ext);
printf("\n*******************ITERATION %d (n %d, n2 %d), ext %p\n\n",iteration_cnt,n,n2,ext);
#endif //DEBUG_LOGMAP
start_meas(intl1_stats);
pi4_p=pi4tab8[iind];
for (i=0; i<(n2>>4); i++) { // steady-state portion
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi8(tmp,((llr_t*)ext)[*pi4_p++],0);
tmp=_mm_insert_epi8(tmp,((llr_t*)ext)[*pi4_p++],1);
tmp=_mm_insert_epi8(tmp,((llr_t*)ext)[*pi4_p++],2);
@@ -941,6 +1358,24 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
tmp=_mm_insert_epi8(tmp,((llr_t*)ext)[*pi4_p++],13);
tmp=_mm_insert_epi8(tmp,((llr_t*)ext)[*pi4_p++],14);
((__m128i *)systematic2)[i]=_mm_insert_epi8(tmp,((llr_t*)ext)[*pi4_p++],15);
#elif defined(__arm__)
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,0);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,1);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,2);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,3);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,4);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,5);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,6);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,7);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,8);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,9);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,10);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,11);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,12);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,13);
tmp=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,14);
((int8x16_t *)systematic2)[i]=vsetq_lane_s8(((llr_t*)ext)[*pi4_p++],tmp,15);
#endif
}
stop_meas(intl1_stats);
@@ -956,6 +1391,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
if ((n2&0x7f) == 0) { // n2 is a multiple of 128 bits
for (i=0; i<(n2>>4); i++) {
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],0);
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],1);
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],2);
@@ -974,9 +1410,33 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],15);
decoded_bytes_interl[i]=(uint16_t) _mm_movemask_epi8(_mm_cmpgt_epi8(tmp,zeros));
((__m128i *)systematic1)[i] = _mm_adds_epi8(_mm_subs_epi8(tmp,((__m128i*)ext)[i]),((__m128i *)systematic0)[i]);
#elif defined(__arm__)
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,0);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,1);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,2);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,3);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,4);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,5);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,6);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,7);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,8);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,9);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,10);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,11);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,12);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,13);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,14);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,15);
uint64x2_t Mask= vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(vcgtq_s8(tmp,zeros), Powers))));
vst1q_lane_u8(&((uint8_t*)&decoded_bytes[i])[0], (uint8x16_t)Mask, 0);
vst1q_lane_u8(&((uint8_t*)&decoded_bytes[i])[1], (uint8x16_t)Mask, 8);
((int8x16_t *)systematic1)[i] = vqaddq_s8(vqsubq_s8(tmp,((int8x16_t*)ext)[i]),((int8x16_t *)systematic0)[i]);
#endif
}
} else {
for (i=0; i<(n2>>4); i++) {
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],0);
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],1);
tmp=_mm_insert_epi8(tmp,ext2[*pi5_p++],2);
@@ -996,7 +1456,29 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
tmp128[i] = _mm_adds_epi8(((__m128i *)ext2)[i],((__m128i *)systematic2)[i]);
((__m128i *)systematic1)[i] = _mm_adds_epi8(_mm_subs_epi8(tmp,((__m128i*)ext)[i]),((__m128i *)systematic0)[i]);
}
#elif defined(__arm__)
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,0);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,1);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,2);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,3);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,4);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,5);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,6);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,7);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,8);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,9);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,10);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,11);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,12);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,13);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,14);
tmp=vsetq_lane_s8(ext2[*pi5_p++],tmp,15);
tmp128[i] = vqaddq_s8(((int8x16_t *)ext2)[i],((int8x16_t *)systematic2)[i]);
((int8x16_t *)systematic1)[i] = vqaddq_s8(vqsubq_s8(tmp,((int8x16_t*)ext)[i]),((int8x16_t *)systematic0)[i]);
#endif
}
}
// Check if we decoded the block
@@ -1007,6 +1489,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
// re-order the decoded bits in theregular order
// as it is presently ordered as 16 sequential columns
#if defined(__x86_64__) || defined(__i386__)
__m128i* dbytes=(__m128i*)decoded_bytes_interl;
__m128i shuffle=SHUFFLE16(7,6,5,4,3,2,1,0);
__m128i mask __attribute__((aligned(16)));
@@ -1021,7 +1504,6 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
tmp2=_mm_and_si128(tmp,mask);
tmp2=_mm_cmpeq_epi16(tmp2,mask);
decoded_bytes[n_128*0+i]=(uint8_t) _mm_movemask_epi8(_mm_packs_epi16(tmp2,zeros));
int j;
for (j=1; j<16; j++) {
@@ -1031,10 +1513,31 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
decoded_bytes[n_128*j +i]=(uint8_t) _mm_movemask_epi8(_mm_packs_epi16(tmp2,zeros));
}
}
#elif defined(__arm__)
uint8x16_t* dbytes=(uint8x16_t*)decoded_bytes_interl;
uint16x8_t mask __attribute__((aligned(16)));
int n_128=n2>>7;
for (i=0; i<n_128; i++) {
mask=vdupq_n_u16(1);
uint8x16_t tmp __attribute__((aligned(16)));
tmp=vcombine_u8(vrev64_u8(((uint8x8_t*)&dbytes[i])[1]),vrev64_u8(((uint8x8_t*)&dbytes[i])[0]));
vst1q_lane_u8(&decoded_bytes[n_128*0+i],(uint8x16_t)vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(tmp, Powers)))),0);
int j;
for (j=1; j<16; j++) {
mask=vshlq_n_u16(mask,1);
vst1q_lane_u8(&decoded_bytes[n_128*0+i],(uint8x16_t)vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(tmp, Powers)))),0);
}
}
#endif
} else {
pi6_p=pi6tab8[iind];
for (i=0; i<(n2>>4); i++) {
#if defined(__x86_64__) || defined(__i386__)
tmp=_mm_insert_epi8(tmp, ((llr_t *)tmp128)[*pi6_p++],7);
tmp=_mm_insert_epi8(tmp, ((llr_t *)tmp128)[*pi6_p++],6);
tmp=_mm_insert_epi8(tmp, ((llr_t *)tmp128)[*pi6_p++],5);
@@ -1053,6 +1556,27 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
tmp=_mm_insert_epi8(tmp, ((llr_t *)tmp128)[*pi6_p++],8);
tmp=_mm_cmpgt_epi8(tmp,zeros);
((uint16_t *)decoded_bytes)[i]=(uint16_t)_mm_movemask_epi8(tmp);
#elif defined(__arm__)
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,7);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,6);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,5);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,4);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,3);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,2);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,1);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,0);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,15);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,14);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,13);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,12);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,11);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,10);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,9);
tmp=vsetq_lane_s8(((llr_t *)tmp128)[*pi6_p++],tmp,8);
uint64x2_t Mask= vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(vcgtq_s8(tmp,zeros), Powers))));
vst1q_lane_u8(&((uint8_t*)&decoded_bytes[i])[0], (uint8x16_t)Mask, 0);
vst1q_lane_u8(&((uint8_t*)&decoded_bytes[i])[1], (uint8x16_t)Mask, 8);
#endif
}
}
@@ -1107,17 +1631,28 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
// do a new iteration if it is not yet decoded
if (iteration_cnt < max_iterations) {
log_map8(systematic1,yparity1,m11,m10,alpha,beta,ext,n2,0,F,offset8_flag,alpha_stats,beta_stats,gamma_stats,ext_stats);
#if defined(__x86_64__) || defined(__i386__)
__m128i* ext_128=(__m128i*) ext;
__m128i* s1_128=(__m128i*) systematic1;
__m128i* s0_128=(__m128i*) systematic0;
#elif defined(__arm__)
int8x16_t* ext_128=(int8x16_t*) ext;
int8x16_t* s1_128=(int8x16_t*) systematic1;
int8x16_t* s0_128=(int8x16_t*) systematic0;
#endif
int myloop=n2>>4;
for (i=0; i<myloop; i++) {
#if defined(__x86_64__) || defined(__i386__)
*ext_128=_mm_adds_epi8(_mm_subs_epi8(*ext_128,*s1_128++),*s0_128++);
#elif defined(__arm__)
*ext_128=vqaddq_s8(vqsubq_s8(*ext_128,*s1_128++),*s0_128++);
#endif
ext_128++;
}
}
}
return(iteration_cnt);
}
+4 -20
View File
@@ -1,29 +1,13 @@
TURBO_SRC = 3gpplte.c 3gpplte_turbo_decoder_sse.c crc_byte.c
TURBO_SRC = 3gpplte_sse.c 3gpplte_turbo_decoder_sse.c crc_byte.c
RATE13CC_SRC = ccoding_byte_lte.c viterbi_lte.c crc_byte.c
RATE12CC_SRC = ccoding_byte.c viterbi.c crc_byte.c
all: turbolte_test rate13cc_test rate12cc_test run_turbo run_rate13cc run_rate13ccdab run_rate12cc
all: 3gpplte_sse
turbolte_test: $(TURBO_SRC)
gcc -o turbo_test $(TURBO_SRC) -DTEST_DEBUG -DUSER_MODE -msse2 -mssse3 -Wall
3gpplte_sse: $(TURBO_SRC)
gcc -o 3gpplte_sse 3gpplte_sse.c -msse4 -Wall -g -ggdb -DMAIN
rate13cc_test: $(RATE13CC_SRC)
gcc -o rate13cc_test $(RATE13CC_SRC) -DTEST_DEBUG -DUSER_MODE -msse2 -mssse3 -Wall
rate12cc_test: $(RATE12CC_SRC)
gcc -o rate12cc_test $(RATE12CC_SRC) -DTEST_DEBUG -DUSER_MODE -msse2 -mssse3 -Wall
run_turbo: turbolte_test
./turbo_test
run_rate13cc: rate13cc_test
./rate13cc_test
run_rate13ccdab: rate13cc_test
./rate13cc_test -d
run_rate12cc: rate12cc_test
./rate12cc_test
clean:
rm *.o
+17 -18
View File
@@ -55,22 +55,22 @@ unsigned char ccodelte_table_rev[128]; // for receiver
void
ccodelte_encode (unsigned int numbits,
unsigned char add_crc,
unsigned char *inPtr,
unsigned char *outPtr,
unsigned short rnti)
ccodelte_encode (int32_t numbits,
uint8_t add_crc,
uint8_t *inPtr,
uint8_t *outPtr,
uint16_t rnti)
{
unsigned int state;
uint32_t state;
unsigned char c, out, first_bit;
char shiftbit=0;
unsigned short c16;
unsigned short next_last_byte=0;
unsigned int crc=0;
uint8_t c, out, first_bit;
int8_t shiftbit=0;
uint16_t c16;
uint16_t next_last_byte=0;
uint32_t crc=0;
#ifdef DEBUG_CCODE
unsigned int dummy=0;
uint32_t dummy=0;
#endif //DEBUG_CCODE
/* The input bit is shifted in position 8 of the state.
@@ -80,20 +80,19 @@ ccodelte_encode (unsigned int numbits,
if (add_crc == 1) {
crc = crc8(inPtr,numbits);
first_bit = 2;
c = (unsigned char)(crc>>24);
c = (uint8_t)(crc>>24);
} else if (add_crc == 2) {
crc = crc16(inPtr,numbits);
#ifdef DEBUG_CCODE
printf("ccode_lte : crc %x\n",crc);
#endif
// scramble with RNTI
crc ^= (((unsigned int)rnti)<<16);
crc ^= (((uint32_t)rnti)<<16);
#ifdef DEBUG_CCODE
printf("ccode_lte : crc %x (rnti %x)\n",crc,rnti);
#endif
first_bit = 2;
// c = (unsigned char)(crc>>24);
c = (unsigned char)((crc>>16)&0xff);
c = (uint8_t)((crc>>16)&0xff);
} else {
next_last_byte = numbits>>3;
first_bit = (numbits-6)&7;
@@ -182,7 +181,7 @@ ccodelte_encode (unsigned int numbits,
// now code 8-bit CRC for UCI
if (add_crc == 1) {
c = (unsigned char)(crc>>24);
c = (uint8_t)(crc>>24);
// for (shiftbit = 0; (shiftbit<8);shiftbit++) {
for (shiftbit = 7; (shiftbit>=0); shiftbit--) {
@@ -209,7 +208,7 @@ ccodelte_encode (unsigned int numbits,
// now code 16-bit CRC for DCI
if (add_crc == 2) {
c16 = (unsigned short)(crc>>16);
c16 = (uint16_t)(crc>>16);
// for (shiftbit = 0; (shiftbit<16);shiftbit++) {
for (shiftbit = 15; (shiftbit>=0); shiftbit--) {
+2 -2
View File
@@ -320,7 +320,7 @@ void threegpplte_turbo_encoder(uint8_t *input,
uint16_t interleaver_f2);
/** \fn void ccodelte_encode(uint32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti)
/** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti)
\brief This function implements the LTE convolutional code of rate 1/3
with a constraint length of 7 bits. The inputs are bit packed in octets
(from MSB to LSB). Trellis tail-biting is included here.
@@ -331,7 +331,7 @@ void threegpplte_turbo_encoder(uint8_t *input,
@param rnti RNTI for CRC scrambling
*/
void
ccodelte_encode (uint32_t numbits,
ccodelte_encode (int32_t numbits,
uint8_t add_crc,
uint8_t *inPtr,
uint8_t *outPtr,
+1 -1
View File
@@ -711,7 +711,7 @@ int lte_rate_matching_turbo_rx(uint32_t RTC,
#endif
if (Kmimo==0 || Mdlharq==0 || C==0 || Qm==0 || Nl==0) {
msg("lte_rate_matching.c: invalid parameters (Kmimo %d, Mdlharq %d, C %d, Qm %d, Nl %d\n",
printf("lte_rate_matching.c: invalid parameters (Kmimo %d, Mdlharq %d, C %d, Qm %d, Nl %d\n",
Kmimo,Mdlharq,C,Qm,Nl);
return(-1);
}
+97 -133
View File
@@ -33,9 +33,8 @@
*/
#ifndef EXPRESSMIMO_TARGET
#include "PHY/sse_intrin.h"
#endif //EXPRESSMIMO_TARGET
extern unsigned char ccodedot11_table[128],ccodedot11_table_rev[128];
@@ -46,12 +45,6 @@ static unsigned char inputs[64][2048];
static unsigned short survivors[64][2048];
static short partial_metrics[64],partial_metrics_new[64];
#ifdef __KERNEL__
#define printf rt_printk
#endif
#ifndef EXPRESSMIMO_TARGET
void phy_viterbi_dot11(char *y,unsigned char *decoded_bytes,unsigned short n)
{
@@ -191,22 +184,34 @@ void phy_generate_viterbi_tables(void)
#define INIT0 0x00000080
#define RESCALE 0x00000040
static __m128i __attribute__((aligned(16))) TB[4*4095*8];
static __m128i metrics0_15,metrics16_31,metrics32_47,metrics48_63,even0_30a,even0_30b,even32_62a,even32_62b,odd1_31a,odd1_31b,odd33_63a,odd33_63b,TBeven0_30,TBeven32_62,TBodd1_31,
TBodd33_63 __attribute__((aligned(16)));
static __m128i rescale,min_state,min_state2 __attribute__((aligned(16)));
void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short n,int offset, int traceback )
{
#if defined(__x86_64__) || defined(__i386__)
__m128i TB[4*4095*8]; // 4 __m128i per input bit (64 states, 8-bits per state = 16-way), 4095 is largest packet size in bytes, 8 bits/byte
__m128i metrics0_15,metrics16_31,metrics32_47,metrics48_63,even0_30a,even0_30b,even32_62a,even32_62b,odd1_31a,odd1_31b,odd33_63a,odd33_63b,TBeven0_30,TBeven32_62,TBodd1_31,TBodd33_63;
__m128i min_state,min_state2;
__m128i *m0_ptr,*m1_ptr,*TB_ptr = &TB[offset<<2];
#elif defined(__arm__)
uint8x16x2_t TB[2*4095*8]; // 2 int8x16_t per input bit, 8 bits / byte, 4095 is largest packet size in bytes
uint8x16_t even0_30a,even0_30b,even32_62a,even32_62b,odd1_31a,odd1_31b,odd33_63a,odd33_63b,TBeven0_30,TBeven32_62,TBodd1_31,TBodd33_63;
uint8x16x2_t metrics0_31,metrics32_63;
uint8x16_t min_state;
uint8x16_t *m0_ptr,*m1_ptr;
uint8x16x2_t *TB_ptr = &TB[offset<<1];
#endif
char *in = y;
unsigned char prev_state0;
@@ -216,6 +221,7 @@ void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short
short position;
// printf("offset %d, TB_ptr %p\n",offset,TB_ptr);
#if defined(__x86_64__) || defined(__i386__)
if (offset == 0) {
// set initial metrics
@@ -225,129 +231,64 @@ void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short
metrics48_63 = _mm_setzero_si128();
}
rescale = _mm_cvtsi32_si128(RESCALE);
#elif defined(__arm__)
if (offset == 0) {
// set initial metrics
/*
print_bytes(metrics0_15,"metrics0_15");
print_bytes(metrics16_31,"metrics16_31");
print_bytes(metrics32_47,"metrics32_47");
print_bytes(metrics48_63,"metrics48_63");
*/
metrics0_31.val[0] = vdupq_n_u8(0); metrics0_31.val[0] = vsetq_lane_u8(INIT0,metrics0_31.val[0],0);
metrics0_31.val[1] = vdupq_n_u8(0);
metrics32_63.val[0] = vdupq_n_u8(0);
metrics32_63.val[1] = vdupq_n_u8(0);
}
#endif
for (position=offset; position<(offset+n); position++) {
//printf("%d : (%d,%d)\n",position,in[0],in[1]);
// get branch metric offsets for the 64 states
table_offset = (in[0]+8 + ((in[1]+8)<<4))<<6;
// printf("Table_offset = %u (in[0]=%d,in[1]=%d)\n",table_offset,in[0],in[1]);
#if defined(__x86_64__) || defined(__i386__)
m0_ptr = (__m128i *)&m0_table[table_offset];
m1_ptr = (__m128i *)&m1_table[table_offset];
// printf("\n");
// even states
even0_30a = _mm_adds_epu8(metrics0_15,m0_ptr[0]);
// print_bytes(even0_30a,"even0_30a");
even32_62a = _mm_adds_epu8(metrics16_31,m0_ptr[1]);
// print_bytes(even32_62a,"even32_62a");
even0_30b = _mm_adds_epu8(metrics32_47,m0_ptr[2]);
// print_bytes(even0_30b,"even0_30b");
even32_62b = _mm_adds_epu8(metrics48_63,m0_ptr[3]);
// print_bytes(even32_62b,"even32_62b");
// printf("\n");
// odd states
odd1_31a = _mm_adds_epu8(metrics0_15,m1_ptr[0]);
// print_bytes(odd1_31a,"odd1_31a");
odd33_63a = _mm_adds_epu8(metrics16_31,m1_ptr[1]);
// print_bytes(odd33_63a,"odd33_63a");
odd1_31b = _mm_adds_epu8(metrics32_47,m1_ptr[2]);
// print_bytes(odd1_31b,"odd1_31b");
odd33_63b = _mm_adds_epu8(metrics48_63,m1_ptr[3]);
// print_bytes(odd33_63b,"odd33_63b");
// select maxima
// printf("\n");
even0_30a = _mm_max_epu8(even0_30a,even0_30b);
// print_bytes(even0_30a,"even0_30a");
even32_62a = _mm_max_epu8(even32_62a,even32_62b);
// print_bytes(even32_62a,"even32_62a");
odd1_31a = _mm_max_epu8(odd1_31a,odd1_31b);
// print_bytes(odd1_31a,"odd1_31a");
odd33_63a = _mm_max_epu8(odd33_63a,odd33_63b);
// print_bytes(odd33_63a,"odd33_63a");
// printf("\n");
// Traceback information
TBeven0_30 = _mm_cmpeq_epi8(even0_30a,even0_30b);
TBeven32_62 = _mm_cmpeq_epi8(even32_62a,even32_62b);
TBodd1_31 = _mm_cmpeq_epi8(odd1_31a,odd1_31b);
TBodd33_63 = _mm_cmpeq_epi8(odd33_63a,odd33_63b);
metrics0_15 = _mm_unpacklo_epi8(even0_30a ,odd1_31a);
metrics16_31 = _mm_unpackhi_epi8(even0_30a ,odd1_31a);
metrics32_47 = _mm_unpacklo_epi8(even32_62a,odd33_63a);
metrics48_63 = _mm_unpackhi_epi8(even32_62a,odd33_63a);
//print_bytes(metrics0_15,"metrics0_15");
//print_bytes(metrics16_31,"metrics16_31");
//print_bytes(metrics32_47,"metrics32_47");
//print_bytes(metrics48_63,"metrics48_63");
TB_ptr[0] = _mm_unpacklo_epi8(TBeven0_30,TBodd1_31);
// print_bytes(TB_ptr[0],"TB0_15");
TB_ptr[0] = _mm_unpacklo_epi8(TBeven0_30,TBodd1_31);
TB_ptr[1] = _mm_unpackhi_epi8(TBeven0_30,TBodd1_31);
// print_bytes(TB_ptr[1],"TB16_31");
TB_ptr[2] = _mm_unpacklo_epi8(TBeven32_62,TBodd33_63);
// print_bytes(TB_ptr[2],"TB32_47");
TB_ptr[3] = _mm_unpackhi_epi8(TBeven32_62,TBodd33_63);
// print_bytes(TB_ptr[3],"TB48_63");
in+=2;
TB_ptr += 4;
@@ -359,50 +300,92 @@ void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short
min_state =_mm_min_epu8(min_state,metrics32_47);
min_state =_mm_min_epu8(min_state,metrics48_63);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
metrics0_15 = _mm_subs_epu8(metrics0_15,min_state);
metrics16_31 = _mm_subs_epu8(metrics16_31,min_state);
metrics32_47 = _mm_subs_epu8(metrics32_47,min_state);
metrics48_63 = _mm_subs_epu8(metrics48_63,min_state);
/*
print_bytes(metrics0_15,"metrics0_15");
print_bytes(metrics16_31,"metrics16_31");
print_bytes(metrics32_47,"metrics32_47");
print_bytes(metrics48_63,"metrics48_63");
*/
#elif defined(__arm__)
m0_ptr = (uint8x16_t *)&m0_table[table_offset];
m1_ptr = (uint8x16_t *)&m1_table[table_offset];
// even states
even0_30a = vqaddq_u8(metrics0_31.val[0],m0_ptr[0]);
even32_62a = vqaddq_u8(metrics0_31.val[1],m0_ptr[1]);
even0_30b = vqaddq_u8(metrics32_63.val[0],m0_ptr[2]);
even32_62b = vqaddq_u8(metrics32_63.val[1],m0_ptr[3]);
// odd states
odd1_31a = vqaddq_u8(metrics0_31.val[0],m1_ptr[0]);
odd33_63a = vqaddq_u8(metrics0_31.val[1],m1_ptr[1]);
odd1_31b = vqaddq_u8(metrics32_63.val[0],m1_ptr[2]);
odd33_63b = vqaddq_u8(metrics32_63.val[1],m1_ptr[3]);
// select maxima
even0_30a = vmaxq_u8(even0_30a,even0_30b);
even32_62a = vmaxq_u8(even32_62a,even32_62b);
odd1_31a = vmaxq_u8(odd1_31a,odd1_31b);
odd33_63a = vmaxq_u8(odd33_63a,odd33_63b);
// Traceback information
TBeven0_30 = vceqq_u8(even0_30a,even0_30b);
TBeven32_62 = vceqq_u8(even32_62a,even32_62b);
TBodd1_31 = vceqq_u8(odd1_31a,odd1_31b);
TBodd33_63 = vceqq_u8(odd33_63a,odd33_63b);
metrics0_31 = vzipq_u8(even0_30a,odd1_31a);
metrics32_63 = vzipq_u8(even32_62a,odd33_63a);
TB_ptr[0] = vzipq_u8(TBeven0_30,TBodd1_31);
TB_ptr[1] = vzipq_u8(TBeven32_62,TBodd33_63);
in+=2;
TB_ptr += 2;
// rescale by subtracting minimum
/****************************************************
USE SSSE instruction phminpos!!!!!!!
****************************************************/
min_state =vminq_u8(metrics0_31.val[0],metrics0_31.val[1]);
min_state =vminq_u8(min_state,metrics32_63.val[0]);
min_state =vminq_u8(min_state,metrics32_63.val[1]);
// here we have 16 maximum metrics from the 64 states
uint8x8_t min_state2 = vpmin_u8(((uint8x8_t*)&min_state)[0],((uint8x8_t*)&min_state)[0]);
// now the 8 maximum in min_state2
min_state2 = vpmin_u8(min_state2,min_state2);
// now the 4 maximum in min_state2, repeated twice
min_state2 = vpmin_u8(min_state2,min_state2);
// now the 2 maximum in min_state2, repeated 4 times
min_state2 = vpmin_u8(min_state2,min_state2);
// now the 1 maximum in min_state2, repeated 8 times
min_state = vcombine_u8(min_state2,min_state2);
// now the 1 maximum in min_state, repeated 16 times
metrics0_31.val[0] = vqsubq_u8(metrics0_31.val[0],min_state);
metrics0_31.val[1] = vqsubq_u8(metrics0_31.val[1],min_state);
metrics32_63.val[0] = vqsubq_u8(metrics32_63.val[0],min_state);
metrics32_63.val[1] = vqsubq_u8(metrics32_63.val[1],min_state);
#endif
}
// Traceback
@@ -429,30 +412,11 @@ void phy_viterbi_dot11_sse2(char *y,unsigned char *decoded_bytes,unsigned short
}
}
#if defined(__x86_64) || defined(__i386__)
_mm_empty();
#endif
}
#else //EXPRESSMIMO_TARGET
void phy_viterbi_dot11(char *y,unsigned char *decoded_bytes,unsigned short n)
{
}
#endif //EXPRESSMIMO_TARGET
/*
void print_bytes(__m128i x,char *s) {
unsigned char *tempb = (unsigned char *)&x;
printf("%s : %u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",s,
tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7],
tempb[8],tempb[9],tempb[10],tempb[11],tempb[12],tempb[13],tempb[14],tempb[15]);
}
*/
#ifdef TEST_DEBUG
#include <stdio.h>
#include <stdlib.h>
+123 -143
View File
@@ -49,21 +49,14 @@
#define msg printf
#endif
#ifndef EXPRESSMIMO_TARGET
#include "PHY/sse_intrin.h"
#endif //EXPRESSMIMO_TARGET
extern uint8_t ccodelte_table[128],ccodelte_table_rev[128];
#ifdef __KERNEL__
#define printf rt_printk
#endif
#ifndef EXPRESSMIMO_TARGET
static int8_t m0_table[64*16*16*16] __attribute__ ((aligned(16)));
static int8_t m1_table[64*16*16*16] __attribute__ ((aligned(16)));
@@ -143,20 +136,33 @@ void print_shorts(__m128i x,char *s) {
#endif // USER_MODE
static __m128i TB[4*8192];
static __m128i metrics0_15,metrics16_31,metrics32_47,metrics48_63,even0_30a,even0_30b,even32_62a,even32_62b,odd1_31a,odd1_31b,odd33_63a,odd33_63b,TBeven0_30,TBeven32_62,TBodd1_31,
TBodd33_63;// __attribute__((aligned(16)));
static __m128i min_state,min_state2;// __attribute__((aligned(16)));
void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
{
static __m128i *m0_ptr,*m1_ptr,*TB_ptr = &TB[0];
#if defined(__x86_64__) || defined(__i386__)
__m128i TB[4*8192];
__m128i *m0_ptr,*m1_ptr,*TB_ptr = &TB[0];
__m128i metrics0_15,metrics16_31,metrics32_47,metrics48_63,even0_30a,even0_30b,even32_62a,even32_62b,odd1_31a,odd1_31b,odd33_63a,odd33_63b,TBeven0_30,TBeven32_62,TBodd1_31,
TBodd33_63;
__m128i min_state,min_state2;
#elif defined(__arm__)
uint8x16x2_t TB[2*8192]; // 2 int8x16_t per input bit, 8 bits / byte, 8192 is largest packet size in bits
uint8x16_t even0_30a,even0_30b,even32_62a,even32_62b,odd1_31a,odd1_31b,odd33_63a,odd33_63b,TBeven0_30,TBeven32_62,TBodd1_31,TBodd33_63;
uint8x16x2_t metrics0_31,metrics32_63;
uint8x16_t min_state;
uint8x16_t *m0_ptr,*m1_ptr;
uint8x16x2_t *TB_ptr = &TB[0];
#endif
int8_t *in = y;
uint8_t prev_state0,maxm,s;
static uint8_t *TB_ptr2;
@@ -167,140 +173,70 @@ void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
// set initial metrics
//debug_msg("Doing viterbi\n");
metrics0_15 = _mm_setzero_si128();
#if defined(__x86_64__) || defined(__i386__)
metrics0_15 = _mm_setzero_si128();
metrics16_31 = _mm_setzero_si128();
metrics32_47 = _mm_setzero_si128();
metrics48_63 = _mm_setzero_si128();
#ifndef USER_MODE
//debug_msg("Doing viterbi 2\n");
#elif defined(__arm__)
metrics0_31.val[0] = vdupq_n_u8(0);
metrics0_31.val[1] = vdupq_n_u8(0);
metrics32_63.val[0] = vdupq_n_u8(0);
metrics32_63.val[1] = vdupq_n_u8(0);
#endif
/*
print_bytes(metrics0_15,"metrics0_15");
print_bytes(metrics16_31,"metrics16_31");
print_bytes(metrics32_47,"metrics32_47");
print_bytes(metrics48_63,"metrics48_63");
*/
for (iter=0; iter<2; iter++) {
in = y;
TB_ptr=&TB[0];
// printf("Iteration %d\n",iter);
for (position=0; position<n; position++) {
// printf("%d/%d : (%d,%d,%d)\n",position,n-1,in[0],in[1],in[2]);
// get branch metric offsets for the 64 states
table_offset = (in[0]+8 + ((in[1]+8)<<4) + ((in[2]+8)<<8))<<6;
/*
printf("Table_offset = %u (in[0]=%d,in[1]=%d,in[2]=%d)\n",table_offset,in[0],in[1],in[2]);
print_bytes("m0",&m0_table[table_offset]);
print_bytes("m1",&m1_table[table_offset]);
*/
#if defined(__x86_64__) || defined(__i386__)
m0_ptr = (__m128i *)&m0_table[table_offset];
m1_ptr = (__m128i *)&m1_table[table_offset];
// printf("\n");
// even states
even0_30a = _mm_adds_epu8(metrics0_15,m0_ptr[0]);
// print_bytes(even0_30a,"even0_30a");
even32_62a = _mm_adds_epu8(metrics16_31,m0_ptr[1]);
// print_bytes(even32_62a,"even32_62a");
even0_30b = _mm_adds_epu8(metrics32_47,m0_ptr[2]);
// print_bytes(even0_30b,"even0_30b");
even32_62b = _mm_adds_epu8(metrics48_63,m0_ptr[3]);
// print_bytes(even32_62b,"even32_62b");
// printf("\n");
// odd states
odd1_31a = _mm_adds_epu8(metrics0_15,m1_ptr[0]);
// print_bytes(odd1_31a,"odd1_31a");
odd33_63a = _mm_adds_epu8(metrics16_31,m1_ptr[1]);
// print_bytes(odd33_63a,"odd33_63a");
odd1_31b = _mm_adds_epu8(metrics32_47,m1_ptr[2]);
// print_bytes(odd1_31b,"odd1_31b");
odd33_63b = _mm_adds_epu8(metrics48_63,m1_ptr[3]);
// print_bytes(odd33_63b,"odd33_63b");
// select maxima
// printf("\n");
even0_30a = _mm_max_epu8(even0_30a,even0_30b);
// print_bytes(even0_30a,"even0_30a");
even32_62a = _mm_max_epu8(even32_62a,even32_62b);
// print_bytes(even32_62a,"even32_62a");
odd1_31a = _mm_max_epu8(odd1_31a,odd1_31b);
// print_bytes(odd1_31a,"odd1_31a");
odd33_63a = _mm_max_epu8(odd33_63a,odd33_63b);
// print_bytes(odd33_63a,"odd33_63a");
// printf("\n");
// Traceback information
TBeven0_30 = _mm_cmpeq_epi8(even0_30a,even0_30b);
TBeven32_62 = _mm_cmpeq_epi8(even32_62a,even32_62b);
TBodd1_31 = _mm_cmpeq_epi8(odd1_31a,odd1_31b);
TBodd33_63 = _mm_cmpeq_epi8(odd33_63a,odd33_63b);
metrics0_15 = _mm_unpacklo_epi8(even0_30a ,odd1_31a);
metrics16_31 = _mm_unpackhi_epi8(even0_30a ,odd1_31a);
metrics32_47 = _mm_unpacklo_epi8(even32_62a,odd33_63a);
metrics48_63 = _mm_unpackhi_epi8(even32_62a,odd33_63a);
/*
print_bytes(metrics0_15,"metrics0_15");
print_bytes(metrics16_31,"metrics16_31");
print_bytes(metrics32_47,"metrics32_47");
print_bytes(metrics48_63,"metrics48_63");
*/
TB_ptr[0] = _mm_unpacklo_epi8(TBeven0_30,TBodd1_31);
// print_bytes(TB_ptr[0],"TB0_15");
TB_ptr[1] = _mm_unpackhi_epi8(TBeven0_30,TBodd1_31);
// print_bytes(TB_ptr[1],"TB16_31");
TB_ptr[2] = _mm_unpacklo_epi8(TBeven32_62,TBodd33_63);
// print_bytes(TB_ptr[2],"TB32_47");
TB_ptr[3] = _mm_unpackhi_epi8(TBeven32_62,TBodd33_63);
// print_bytes(TB_ptr[3],"TB48_63");
in+=3;
TB_ptr += 4;
@@ -313,50 +249,90 @@ void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
min_state =_mm_min_epu8(min_state,metrics32_47);
min_state =_mm_min_epu8(min_state,metrics48_63);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
min_state2 = min_state;
min_state = _mm_unpacklo_epi8(min_state,min_state);
min_state2 = _mm_unpackhi_epi8(min_state2,min_state2);
min_state = _mm_min_epu8(min_state,min_state2);
// print_bytes(min_state,"min_state");
metrics0_15 = _mm_subs_epu8(metrics0_15,min_state);
metrics16_31 = _mm_subs_epu8(metrics16_31,min_state);
metrics32_47 = _mm_subs_epu8(metrics32_47,min_state);
metrics48_63 = _mm_subs_epu8(metrics48_63,min_state);
#elif defined(__arm__)
m0_ptr = (uint8x16_t *)&m0_table[table_offset];
m1_ptr = (uint8x16_t *)&m1_table[table_offset];
/*
print_bytes("metrics0_15",&metrics0_15);
print_bytes("metrics16_31",&metrics16_31);
print_bytes("metrics32_47",&metrics32_47);
print_bytes("metrics48_63",&metrics48_63);
printf("\n");
*/
// even states
even0_30a = vqaddq_u8(metrics0_31.val[0],m0_ptr[0]);
even32_62a = vqaddq_u8(metrics0_31.val[1],m0_ptr[1]);
even0_30b = vqaddq_u8(metrics32_63.val[0],m0_ptr[2]);
even32_62b = vqaddq_u8(metrics32_63.val[1],m0_ptr[3]);
// odd states
odd1_31a = vqaddq_u8(metrics0_31.val[0],m1_ptr[0]);
odd33_63a = vqaddq_u8(metrics0_31.val[1],m1_ptr[1]);
odd1_31b = vqaddq_u8(metrics32_63.val[0],m1_ptr[2]);
odd33_63b = vqaddq_u8(metrics32_63.val[1],m1_ptr[3]);
// select maxima
even0_30a = vmaxq_u8(even0_30a,even0_30b);
even32_62a = vmaxq_u8(even32_62a,even32_62b);
odd1_31a = vmaxq_u8(odd1_31a,odd1_31b);
odd33_63a = vmaxq_u8(odd33_63a,odd33_63b);
// Traceback information
TBeven0_30 = vceqq_u8(even0_30a,even0_30b);
TBeven32_62 = vceqq_u8(even32_62a,even32_62b);
TBodd1_31 = vceqq_u8(odd1_31a,odd1_31b);
TBodd33_63 = vceqq_u8(odd33_63a,odd33_63b);
metrics0_31 = vzipq_u8(even0_30a,odd1_31a);
metrics32_63 = vzipq_u8(even32_62a,odd33_63a);
TB_ptr[0] = vzipq_u8(TBeven0_30,TBodd1_31);
TB_ptr[1] = vzipq_u8(TBeven32_62,TBodd33_63);
in+=2;
TB_ptr += 2;
// rescale by subtracting minimum
/****************************************************
USE SSSE instruction phminpos!!!!!!!
****************************************************/
min_state =vminq_u8(metrics0_31.val[0],metrics0_31.val[1]);
min_state =vminq_u8(min_state,metrics32_63.val[0]);
min_state =vminq_u8(min_state,metrics32_63.val[1]);
// here we have 16 maximum metrics from the 64 states
uint8x8_t min_state2 = vpmin_u8(((uint8x8_t*)&min_state)[0],((uint8x8_t*)&min_state)[0]);
// now the 8 maximum in min_state2
min_state2 = vpmin_u8(min_state2,min_state2);
// now the 4 maximum in min_state2, repeated twice
min_state2 = vpmin_u8(min_state2,min_state2);
// now the 2 maximum in min_state2, repeated 4 times
min_state2 = vpmin_u8(min_state2,min_state2);
// now the 1 maximum in min_state2, repeated 8 times
min_state = vcombine_u8(min_state2,min_state2);
// now the 1 maximum in min_state, repeated 16 times
metrics0_31.val[0] = vqsubq_u8(metrics0_31.val[0],min_state);
metrics0_31.val[1] = vqsubq_u8(metrics0_31.val[1],min_state);
metrics32_63.val[0] = vqsubq_u8(metrics32_63.val[0],min_state);
metrics32_63.val[1] = vqsubq_u8(metrics32_63.val[1],min_state);
#endif
}
} // iteration
@@ -365,6 +341,7 @@ void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
prev_state0 = 0;
maxm = 0;
#if defined(__x86_64__) || defined(__i386__)
for (s=0; s<16; s++)
if (((uint8_t *)&metrics0_15)[s] > maxm) {
maxm = ((uint8_t *)&metrics0_15)[s];
@@ -389,17 +366,39 @@ void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
prev_state0 = s+48;
}
// printf("Max state %d\n",prev_state0);
#elif defined(__arm__)
for (s=0; s<16; s++)
if (((uint8_t *)&metrics0_31.val[0])[s] > maxm) {
maxm = ((uint8_t *)&metrics0_31.val[0])[s];
prev_state0 = s;
}
for (s=0; s<16; s++)
if (((uint8_t *)&metrics0_31.val[1])[s] > maxm) {
maxm = ((uint8_t *)&metrics0_31.val[1])[s];
prev_state0 = s+16;
}
for (s=0; s<16; s++)
if (((uint8_t *)&metrics32_63.val[0])[s] > maxm) {
maxm = ((uint8_t *)&metrics32_63.val[0])[s];
prev_state0 = s+32;
}
for (s=0; s<16; s++)
if (((uint8_t *)&metrics32_63.val[1])[s] > maxm) {
maxm = ((uint8_t *)&metrics32_63.val[1])[s];
prev_state0 = s+48;
}
#endif
TB_ptr2 = (uint8_t *)&TB[(n-1)*4];
for (position = n-1 ; position>-1; position--) {
// if ((position%8) == 0)
// printf("%d: %x\n",1+(position>>3),decoded_bytes[1+(position>>3)]);
decoded_bytes[(position)>>3] += (prev_state0 & 0x1)<<(7-(position & 0x7));
// printf("pos %d : ps = %d -> %d\n",position,prev_state0,TB_ptr2[prev_state0]);
if (TB_ptr2[prev_state0] == 0)
prev_state0 = (prev_state0 >> 1);
@@ -409,32 +408,13 @@ void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
TB_ptr2-=64;
}
// printf("Max state %d\n",prev_state0);
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
#else //EXPRESSMIMO_TARGET
void phy_viterbi_lte(int8_t *y,uint8_t *decoded_bytes,uint16_t n)
{
}
#endif //EXPRESSMIMO_TARGET
/*
void print_bytes(__m128i x,int8_t *s) {
uint8_t *tempb = (uint8_t *)&x;
printf("%s : %u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",s,
tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7],
tempb[8],tempb[9],tempb[10],tempb[11],tempb[12],tempb[13],tempb[14],tempb[15]);
}
*/
#ifdef TEST_DEBUG
int test_viterbi(uint8_t dabflag)
{
+4 -3
View File
@@ -52,6 +52,7 @@
#include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_PHY
#include "assertions.h"
#include <math.h>
#ifdef EXMIMO
extern openair0_rf_map rf_map[MAX_NUM_CCs];
@@ -127,6 +128,8 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
{
LTE_DL_FRAME_PARMS *lte_frame_parms = &PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms;
LTE_eNB_UE_stats *eNB_UE_stats = PHY_vars_eNB_g[Mod_id][CC_id]->eNB_UE_stats;
int32_t rx_total_gain_eNB_dB = PHY_vars_eNB_g[Mod_id][CC_id]->rx_total_gain_eNB_dB;
int i;
LOG_D(PHY,"[eNB%d] CCid %d Frame %d: Applying radioResourceConfigCommon\n",Mod_id,CC_id,PHY_vars_eNB_g[Mod_id][CC_id]->proc[8].frame_tx);
@@ -885,10 +888,8 @@ void phy_init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms)
ccodelte_init();
ccodelte_init_inv();
#ifndef EXPRESSMIMO_TARGET
phy_generate_viterbi_tables();
phy_generate_viterbi_tables_lte();
#endif //EXPRESSMIMO_TARGET
init_td8();
init_td16();
@@ -1234,7 +1235,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *phy_vars_eNB,
LTE_eNB_PUSCH** const eNB_pusch_vars = phy_vars_eNB->lte_eNB_pusch_vars;
LTE_eNB_SRS* const eNB_srs_vars = phy_vars_eNB->lte_eNB_srs_vars;
LTE_eNB_PRACH* const eNB_prach_vars = &phy_vars_eNB->lte_eNB_prach_vars;
int i, j, eNB_id, UE_id;
int i, j, eNB_id, UE_id;
phy_vars_eNB->total_dlsch_bitrate = 0;
phy_vars_eNB->total_transmitted_bits = 0;
+6
View File
@@ -33,6 +33,8 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
uint8_t log2_osf;
LOG_I(PHY,"Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
if (frame_parms->Ncp==1) {
frame_parms->nb_prefix_samples0=512;
frame_parms->nb_prefix_samples = 512;
@@ -115,6 +117,8 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
frame_parms->nb_prefix_samples0>>=(2-log2_osf);
frame_parms->N_RBGS = 2;
frame_parms->N_RBG = 13;
break;
case 15:
@@ -145,6 +149,8 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
break;
}
printf("lte_parms.c: Setting N_RB_DL to %d, ofdm_symbol_size %d\n",frame_parms->N_RB_DL, frame_parms->ofdm_symbol_size);
// frame_parms->tdd_config=3;
return(0);
}
+3 -1
View File
@@ -162,11 +162,13 @@ We estimate the frequency offset by calculating the phase difference between cha
\param frame_parms pointer to LTE frame parameters
\param l symbol within slot
\param freq_offset pointer to the returned frequency offset
\param reset When non-zer it resets the filter to the initial value (set whenever tuning has been changed or for a one-shot estimate)
*/
int lte_est_freq_offset(int **dl_ch_estimates,
LTE_DL_FRAME_PARMS *frame_parms,
int l,
int* freq_offset);
int* freq_offset,
int reset);
int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
LTE_DL_FRAME_PARMS *frame_parms,
+56 -56
View File
@@ -26,187 +26,187 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
short filt24_0[24] = {
short filt24_0[24] __attribute__((aligned(16))) ={
2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_0_dcl[24] = {
short filt24_0_dcl[24] __attribute__((aligned(16))) ={
2341,4681,7022,9362,11703,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_0_dcr[24] = {
short filt24_0_dcr[24] __attribute__((aligned(16))) ={
2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_1[24] = {
short filt24_1[24] __attribute__((aligned(16))) ={
0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_1_dcl[24] = {
short filt24_1_dcl[24] __attribute__((aligned(16))) ={
0,4681,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_1_dcr[24] = {
short filt24_1_dcr[24] __attribute__((aligned(16))) ={
0,2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_2[24] = {
short filt24_2[24] __attribute__((aligned(16))) ={
0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_2_dcl[24] = {
short filt24_2_dcl[24] __attribute__((aligned(16))) ={
0,0,2341,4681,7022,9362, 11703,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_2_dcr[24] = {
short filt24_2_dcr[24] __attribute__((aligned(16))) ={
0,0,2730,5461,8192,10922,13653,16384,14043,11703,9362,4681,2341,0,0,0,0,0,0,0,0,0,0,0
};
// X X X Y | X X X X | X Y X X
short filt24_3[24] = {
short filt24_3[24] __attribute__((aligned(16))) ={
0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0
};
short filt24_3_dcl[24] = {
short filt24_3_dcl[24] __attribute__((aligned(16))) ={
0,0,0,2341,4681,7022,9362,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0
};
// X X X Y | X X DC X X | X Y X X
short filt24_3_dcr[24] = {
short filt24_3_dcr[24] __attribute__((aligned(16))) ={
0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,7022,4681,2341,0,0,0,0,0,0,0,0,0,0
};
short filt24_4[24] = {
short filt24_4[24] __attribute__((aligned(16))) ={
0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0
};
short filt24_4_dcl[24] = {
short filt24_4_dcl[24] __attribute__((aligned(16))) ={
0,0,0,0,2341,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0
};
short filt24_4_dcr[24] = {
short filt24_4_dcr[24] __attribute__((aligned(16))) ={
0,0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,7022,4681,2341,0,0,0,0,0,0,0,0,0
};
short filt24_5[24] = {
short filt24_5[24] __attribute__((aligned(16))) ={
0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0
};
// X X X Y | X X DC X X | X Y X X
short filt24_5_dcl[24] = {
short filt24_5_dcl[24] __attribute__((aligned(16))) ={
0,0,0,0,0,2341,4681,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0
};
short filt24_5_dcr[24] = {
short filt24_5_dcr[24] __attribute__((aligned(16))) ={
0,0,0,0,0,2730,5461,8192,10922,13653,16384,11703,9362,7022,4681,2730,0,0,0,0,0,0,0,0
};
short filt24_6[24] = {
short filt24_6[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0
};
short filt24_6_dcl[24] = {
short filt24_6_dcl[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,4681,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0
};
short filt24_6_dcr[24] = {
short filt24_6_dcr[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0,0
};
short filt24_7[24] = {
short filt24_7[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0
};
short filt24_7_dcl[24] = {
short filt24_7_dcl[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,0,4681,7022,9362,11703,14043,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0
};
short filt24_7_dcr[24] = {
short filt24_7_dcr[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,14043,11703,9362,7022,4681,0,0,0,0,0,0
};
short filt24_0l[24] = {
short filt24_0l[24] __attribute__((aligned(16))) ={
30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_1l[24] = {
short filt24_1l[24] __attribute__((aligned(16))) ={
0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_2l[24] = {
short filt24_2l[24] __attribute__((aligned(16))) ={
0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_3l[24] = {
short filt24_3l[24] __attribute__((aligned(16))) ={
//0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0};
0,0,0,0,0,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0
};
short filt24_4l[24] = {
short filt24_4l[24] __attribute__((aligned(16))) ={
0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0
};
short filt24_5l[24] = {
short filt24_5l[24] __attribute__((aligned(16))) ={
0,0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0
};
short filt24_6l[24] = {
short filt24_6l[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0
};
short filt24_7l[24] = {
short filt24_7l[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,0,30037,27306,24576,21845,19114,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0
};
short filt24_0l2[24] = {
short filt24_0l2[24] __attribute__((aligned(16))) ={
2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_1l2[24] = {
short filt24_1l2[24] __attribute__((aligned(16))) ={
0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_2l2[24] = {
short filt24_2l2[24] __attribute__((aligned(16))) ={
-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_3l2[24] = {
short filt24_3l2[24] __attribute__((aligned(16))) ={
-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0,0
};
short filt24_4l2[24] = {
short filt24_4l2[24] __attribute__((aligned(16))) ={
-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0,0
};
short filt24_5l2[24] = {
short filt24_5l2[24] __attribute__((aligned(16))) ={
0,-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0,0
};
short filt24_6l2[24] = {
short filt24_6l2[24] __attribute__((aligned(16))) ={
-13653,-10922,-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0,0
};
short filt24_7l2[24] = {
short filt24_7l2[24] __attribute__((aligned(16))) ={
0,-13653,-10922,-8192,-5461,-2730,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,0,0,0,0,0
};
short filt24_0r[24] = {
short filt24_0r[24] __attribute__((aligned(16))) ={
2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_1r[24] = {
short filt24_1r[24] __attribute__((aligned(16))) ={
0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_2r[24] = {
short filt24_2r[24] __attribute__((aligned(16))) ={
0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0,0
};
short filt24_3r[24] = {
short filt24_3r[24] __attribute__((aligned(16))) ={
0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0,0
};
short filt24_4r[24] = {
short filt24_4r[24] __attribute__((aligned(16))) ={
0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0,0
};
short filt24_5r[24] = {
short filt24_5r[24] __attribute__((aligned(16))) ={
0,0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0,0
};
short filt24_6r[24] = {
short filt24_6r[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0,0
};
short filt24_7r[24] = {
short filt24_7r[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,19114,21845,24576,27306,30037,0,0,0,0,0,0
};
short filt24_0r2[24] = { /****/
short filt24_0r2[24] __attribute__((aligned(16))) ={ /****/
2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0,0,0,0
};
short filt24_1r2[24] = {
short filt24_1r2[24] __attribute__((aligned(16))) ={
0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0,0,0
};
short filt24_2r2[24] = {
short filt24_2r2[24] __attribute__((aligned(16))) ={
0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0,0
};
short filt24_3r2[24] = {
short filt24_3r2[24] __attribute__((aligned(16))) ={
0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0,0
};
short filt24_4r2[24] = {
short filt24_4r2[24] __attribute__((aligned(16))) ={
0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0,0
};
short filt24_5r2[24] = {
short filt24_5r2[24] __attribute__((aligned(16))) ={
0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0,0
};
short filt24_6r2[24] = {
short filt24_6r2[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653,0
};
short filt24_7r2[24] = {
short filt24_7r2[24] __attribute__((aligned(16))) ={
0,0,0,0,0,0,0,2730,5461,8192,10922,13653,16384,13653,10922,8192,5461,2730,0,-2730,-5461,-8192,-10922,-13653
};
@@ -299,11 +299,17 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
{
uint16_t re;
int16_t amp;
#if defined(__x86_64__) || defined(__i386__)
__m128i *ul_ch_mag128,*ul_ch_magb128,*rxdataF_comp128;
rxdataF_comp128 = (__m128i *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128 = (__m128i *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
ul_ch_magb128 = (__m128i *)&ul_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
int16x8_t *ul_ch_mag128,*ul_ch_magb128,*rxdataF_comp128;
rxdataF_comp128 = (int16x8_t*)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128 = (int16x8_t*)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
ul_ch_magb128 = (int16x8_t*)&ul_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
#endif
for (re=0; re<(Msc_RS>>2); re++) {
@@ -313,15 +319,25 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms,
amp=255;
// printf("freq_eq: symbol %d re %d => %d,%d,%d, (%d) (%d,%d) => ",symbol,re,*((int16_t*)(&ul_ch_mag128[re])),amp,inv_ch[8*amp],*((int16_t*)(&ul_ch_mag128[re]))*inv_ch[8*amp],*(int16_t*)&(rxdataF_comp128[re]),*(1+(int16_t*)&(rxdataF_comp128[re])));
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128[re] = _mm_mullo_epi16(rxdataF_comp128[re],*((__m128i *)&inv_ch[8*amp]));
if (Qm==4)
ul_ch_mag128[re] = _mm_set1_epi16(324); // this is 512*2/sqrt(10)
ul_ch_mag128[re] = _mm_set1_epi16(324); // this is 512*2/sqrt(10)
else {
ul_ch_mag128[re] = _mm_set1_epi16(316); // this is 512*4/sqrt(42)
ul_ch_mag128[re] = _mm_set1_epi16(316); // this is 512*4/sqrt(42)
ul_ch_magb128[re] = _mm_set1_epi16(158); // this is 512*2/sqrt(42)
}
#elif defined(__arm__)
rxdataF_comp128[re] = vmulq_s16(rxdataF_comp128[re],*((int16x8_t *)&inv_ch[8*amp]));
if (Qm==4)
ul_ch_mag128[re] = vdupq_n_s16(324); // this is 512*2/sqrt(10)
else {
ul_ch_mag128[re] = vdupq_n_s16(316); // this is 512*4/sqrt(42)
ul_ch_magb128[re] = vdupq_n_s16(158); // this is 512*2/sqrt(42)
}
#endif
// printf("(%d,%d)\n",*(int16_t*)&(rxdataF_comp128[re]),*(1+(int16_t*)&(rxdataF_comp128[re])));
}
@@ -52,7 +52,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
short ch[2], *pil, *rxF, *dl_bf_ch, *dl_bf_ch_prev;
short *fl, *fm, *fr, *fl_dc, *fm_dc, *fr_dc, *f1, *f2l, *f2r;
unsigned int *rb_alloc;
unsigned int *rballoc;
int **rxdataF;
int32_t **dl_bf_ch_estimates;
int uespec_pilot[300];
@@ -64,7 +64,11 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
harq_pid = dlsch_ue[0]->current_harq_pid;
dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
rb_alloc = dlsch0_harq->rb_alloc;
if (((frame_parms->Ncp == NORMAL) && (symbol>=7)) ||
((frame_parms->Ncp == EXTENDED) && (symbol>=6)))
rballoc = dlsch0_harq->rb_alloc_odd;
else
rballoc = dlsch0_harq->rb_alloc_even;
rxdataF = phy_vars_ue->lte_ue_common_vars.rxdataF;
@@ -205,13 +209,13 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
rb_alloc_ind = (rballoc[0]>>rb) & 1;
else if (rb < 64)
rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
else if (rb < 96)
rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
else if (rb < 100)
rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
else
rb_alloc_ind = 0;
@@ -256,13 +260,13 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
skip_half=0;
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
rb_alloc_ind = (rballoc[0]>>rb) & 1;
else if (rb < 64)
rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
else if (rb < 96)
rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
else if (rb < 100)
rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
else
rb_alloc_ind = 0;
@@ -403,13 +407,13 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// Do middle RB (around DC)
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
rb_alloc_ind = (rballoc[0]>>rb) & 1;
else if (rb < 64)
rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
else if (rb < 96)
rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
else if (rb < 100)
rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
else
rb_alloc_ind = 0;
@@ -493,13 +497,13 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
skip_half=0;
if (rb < 32)
rb_alloc_ind = (rb_alloc[0]>>rb) & 1;
rb_alloc_ind = (rballoc[0]>>rb) & 1;
else if (rb < 64)
rb_alloc_ind = (rb_alloc[1]>>(rb-32)) & 1;
rb_alloc_ind = (rballoc[1]>>(rb-32)) & 1;
else if (rb < 96)
rb_alloc_ind = (rb_alloc[2]>>(rb-64)) & 1;
rb_alloc_ind = (rballoc[2]>>(rb-64)) & 1;
else if (rb < 100)
rb_alloc_ind = (rb_alloc[3]>>(rb-96)) & 1;
rb_alloc_ind = (rballoc[3]>>(rb-96)) & 1;
else
rb_alloc_ind = 0;
@@ -46,7 +46,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
unsigned char nu,aarx;
unsigned short k;
unsigned int rb,pilot_cnt;
short ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev,*f,*f2,*fl,*f2l2,*fr,*f2r2,*f2_dc,*f_dc;
int16_t ch[2],*pil,*rxF,*dl_ch,*dl_ch_prev,*f,*f2,*fl,*f2l2,*fr,*f2r2,*f2_dc,*f_dc;
int ch_offset,symbol_offset;
// unsigned int n;
// int i;
@@ -189,14 +189,13 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
for (aarx=0; aarx<phy_vars_ue->lte_frame_parms.nb_antennas_rx; aarx++) {
pil = (short *)&pilot[p][0];
rxF = (short *)&rxdataF[aarx][((symbol_offset+k+phy_vars_ue->lte_frame_parms.first_carrier_offset))];
dl_ch = (short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
pil = (int16_t *)&pilot[p][0];
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+k+phy_vars_ue->lte_frame_parms.first_carrier_offset))];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
// if (eNb_id==0)
memset(dl_ch,0,4*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size));
if (phy_vars_ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha
multadd_complex_vector_real_scalar(dl_ch-(phy_vars_ue->lte_frame_parms.ofdm_symbol_size<<1),
phy_vars_ue->ch_est_alpha,dl_ch-(phy_vars_ue->lte_frame_parms.ofdm_symbol_size<<1),
@@ -209,8 +208,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
//First half of pilots
// Treat first 2 pilots specially (left edge)
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
multadd_real_vector_complex_scalar(fl,
ch,
@@ -220,8 +219,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
multadd_real_vector_complex_scalar(f2l2,
ch,
@@ -233,15 +232,15 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
for (pilot_cnt=2; pilot_cnt<((phy_vars_ue->lte_frame_parms.N_RB_DL)-1); pilot_cnt+=2) {
// printf("%d\n",dl_ch-(short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
// printf("%d\n",dl_ch-(int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
// printf("pilot[%d][%d] (%d,%d)\n",p,pilot_cnt,pil[0],pil[1]);
// printf("rx[%d] -> (%d,%d)\n", k, rxF[0], rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15); //Re
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15); //Im
// printf("**rb %d %d\n",rb,dl_ch-(short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); //Re
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); //Im
// printf("**rb %d %d\n",rb,dl_ch-(int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
@@ -256,9 +255,9 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// printf("rx[%d] -> (%d,%d)\n", k+6, rxF[0], rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
// printf("**rb %d %d\n",rb,dl_ch-(short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("**rb %d %d\n",rb,dl_ch-(int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
@@ -277,17 +276,17 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
if (k > 6)
k -=6;
rxF = (short *)&rxdataF[aarx][((symbol_offset+1+k))];
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))];
for (pilot_cnt=0; pilot_cnt<((phy_vars_ue->lte_frame_parms.N_RB_DL)-3); pilot_cnt+=2) {
// printf("pilot[%d][%d] (%d,%d)\n",p,pilot_cnt,pil[0],pil[1]);
// printf("rx[%d] -> (%d,%d)\n", k+6, rxF[0], rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("**rb %d %d\n",rb,dl_ch-(short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
// printf("**rb %d %d\n",rb,dl_ch-(int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
multadd_real_vector_complex_scalar(f,
ch,
dl_ch,
@@ -296,10 +295,10 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("**rb %d %d\n",rb,dl_ch-(short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
// printf("**rb %d %d\n",rb,dl_ch-(int16_T *)&dl_ch_estimates[(p<<1)+aarx][ch_offset]);
multadd_real_vector_complex_scalar(f2,
ch,
dl_ch,
@@ -310,8 +309,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
}
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("pilot 49: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
multadd_real_vector_complex_scalar(fr,
@@ -322,8 +321,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("pilot 50: rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
multadd_real_vector_complex_scalar(f2r2,
ch,
@@ -337,8 +336,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
//printf("Channel estimation\n");
// Treat first 2 pilots specially (left edge)
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 0 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -355,8 +354,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -378,8 +377,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// printf("pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
// printf("rx[%d][%d] -> (%d,%d)\n",p,phy_vars_ue->lte_frame_parms.first_carrier_offset + phy_vars_ue->lte_frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -397,8 +396,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -416,8 +415,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
}
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 24: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -435,10 +434,10 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// printf("Second half\n");
// Second half of RBs
rxF = (short *)&rxdataF[aarx][((symbol_offset+1+k))];
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+k))];
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 25: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -459,8 +458,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// printf("* pilot[%d][%d] (%d,%d)\n",p,rb,pil[0],pil[1]);
// printf("rx[%d][%d] -> (%d,%d)\n",p,phy_vars_ue->lte_frame_parms.first_carrier_offset + phy_vars_ue->lte_frame_parms.nushift + 6*rb+(3*p),rxF[0],rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",26+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -476,8 +475,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot %d : rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",27+pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -495,8 +494,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
}
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
printf("pilot 49: rxF -> (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
@@ -514,8 +513,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_CH
@@ -541,8 +540,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// phy_vars_ue->lte_frame_parms.first_carrier_offset + phy_vars_ue->lte_frame_parms.nushift + 6*rb+(3*p),
// rxF[0],
// rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
//printf("ch -> (%d,%d)\n",ch[0],ch[1]);
multadd_real_vector_complex_scalar(f,
ch,
@@ -552,8 +551,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
//printf("ch -> (%d,%d)\n",ch[0],ch[1]);
multadd_real_vector_complex_scalar(f2,
ch,
@@ -565,8 +564,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
}
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
// printf("ch -> (%d,%d)\n",ch[0],ch[1]);
multadd_real_vector_complex_scalar(f,
ch,
@@ -577,9 +576,9 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
//printf("Second half\n");
//Second half of RBs
rxF = (short *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))];
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
rxF = (int16_t *)&rxdataF[aarx][((symbol_offset+1+nushift + (3*p)))];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f2,
ch,
@@ -596,8 +595,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// phy_vars_ue->lte_frame_parms.first_carrier_offset + phy_vars_ue->lte_frame_parms.nushift + 6*rb+(3*p),
// rxF[0],
// rxF[1]);
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f,
ch,
@@ -607,8 +606,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
rxF+=12;
dl_ch+=8;
ch[0] = (short)(((int)pil[0]*rxF[0] - (int)pil[1]*rxF[1])>>15);
ch[1] = (short)(((int)pil[0]*rxF[1] + (int)pil[1]*rxF[0])>>15);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
multadd_real_vector_complex_scalar(f2,
ch,
@@ -628,7 +627,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
// Temporal Interpolation
// printf("ch_offset %d\n",ch_offset);
dl_ch = (short *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
dl_ch = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][ch_offset];
if (phy_vars_ue->high_speed_flag == 0) {
multadd_complex_vector_real_scalar(dl_ch,
@@ -637,8 +636,8 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
} else { // high_speed_flag == 1
if (symbol == 0) {
// printf("Interpolating %d->0\n",4-phy_vars_ue->lte_frame_parms.Ncp);
// dl_ch_prev = (short *)&dl_ch_estimates[(p<<1)+aarx][(4-phy_vars_ue->lte_frame_parms.Ncp)*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
dl_ch_prev = (short *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
// dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][(4-phy_vars_ue->lte_frame_parms.Ncp)*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot3*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)),1,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)),0,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
@@ -647,7 +646,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((phy_vars_ue->lte_frame_parms.ofdm_symbol_size)<<1)),0,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
} // this is 1/3,2/3 combination for pilots spaced by 3 symbols
else if (symbol == pilot1) {
dl_ch_prev = (short *)&dl_ch_estimates[(p<<1)+aarx][0];
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][0];
if (phy_vars_ue->lte_frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)),1,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
@@ -666,7 +665,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*((phy_vars_ue->lte_frame_parms.ofdm_symbol_size)<<1)),0,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
} // pilot spacing 3 symbols (1/3,2/3 combination)
} else if (symbol == pilot2) {
dl_ch_prev = (short *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot1*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
multadd_complex_vector_real_scalar(dl_ch_prev,21845,dl_ch_prev+(2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)),1,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
multadd_complex_vector_real_scalar(dl_ch,10923,dl_ch_prev+(2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)),0,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
@@ -675,7 +674,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *phy_vars_ue,
multadd_complex_vector_real_scalar(dl_ch,21845,dl_ch_prev+(2*((phy_vars_ue->lte_frame_parms.ofdm_symbol_size)<<1)),0,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
} else { // symbol == pilot3
// printf("Interpolating 0->%d\n",4-phy_vars_ue->lte_frame_parms.Ncp);
dl_ch_prev = (short *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
dl_ch_prev = (int16_t *)&dl_ch_estimates[(p<<1)+aarx][pilot2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
if (phy_vars_ue->lte_frame_parms.Ncp==0) {// pilot spacing 4 symbols (1/4,1/2,3/4 combination)
multadd_complex_vector_real_scalar(dl_ch_prev,24576,dl_ch_prev+(2*(phy_vars_ue->lte_frame_parms.ofdm_symbol_size)),1,phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
@@ -35,7 +35,11 @@
#include "PHY/defs.h"
//#define DEBUG_PHY
#if defined(__x86_64__) || defined(__i386__)
__m128i avg128F;
#elif defined(__arm__)
int32x4_t avg128F;
#endif
//compute average channel_level on each (TX,RX) antenna pair
int dl_channel_level(int16_t *dl_ch,
@@ -43,10 +47,15 @@ int dl_channel_level(int16_t *dl_ch,
{
int16_t rb;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128;
#elif defined(__arm__)
int16x4_t *dl_ch128;
#endif
int avg;
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128F = _mm_setzero_si128();
dl_ch128=(__m128i *)dl_ch;
@@ -59,24 +68,44 @@ int dl_channel_level(int16_t *dl_ch,
dl_ch128+=3;
}
#elif defined(__arm__)
avg128F = vdupq_n_s32(0);
dl_ch128=(int16x4_t *)dl_ch;
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[0],dl_ch128[0]));
avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[1],dl_ch128[1]));
avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[2],dl_ch128[2]));
avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[3],dl_ch128[3]));
avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[4],dl_ch128[4]));
avg128F = vqaddq_s32(avg128F,vmull_s16(dl_ch128[5],dl_ch128[5]));
dl_ch128+=6;
}
#endif
DevAssert( frame_parms->N_RB_DL );
avg = (((int*)&avg128F)[0] +
((int*)&avg128F)[1] +
((int*)&avg128F)[2] +
((int*)&avg128F)[3])/(frame_parms->N_RB_DL*12);
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(avg);
}
int lte_est_freq_offset(int **dl_ch_estimates,
LTE_DL_FRAME_PARMS *frame_parms,
int l,
int* freq_offset)
int* freq_offset,
int reset)
{
int ch_offset, omega, dl_ch_shift;
@@ -89,6 +118,9 @@ int lte_est_freq_offset(int **dl_ch_estimates,
int coef = 1<<10;
int ncoef = 32767 - coef;
// initialize the averaging filter to initial value
if (reset!=0)
first_run=1;
ch_offset = (l*(frame_parms->ofdm_symbol_size));
@@ -134,13 +166,13 @@ int lte_est_freq_offset(int **dl_ch_estimates,
omega_cpx->i += ((struct complex16*) &omega)->i;
// phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
// LOG_D(PHY,"omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
// LOG_I(PHY,"omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
}
// phase_offset /= (frame_parms->nb_antennas_rx*frame_parms->nb_antennas_tx);
freq_offset_est = (int) (phase_offset/(2*M_PI)/(frame_parms->Ncp==NORMAL ? (285.8e-6):(2.5e-4))); //2.5e-4 is the time between pilot symbols
// LOG_D(PHY,"symbol %d : freq_offset_est %d\n",l,freq_offset_est);
// LOG_I(PHY,"symbol %d : freq_offset_est %d\n",l,freq_offset_est);
// update freq_offset with phase_offset using a moving average filter
if (first_run == 1) {
+5 -14
View File
@@ -39,9 +39,7 @@
#include "SCHED/extern.h"
#include "MAC_INTERFACE/defs.h"
#include "MAC_INTERFACE/extern.h"
#ifdef USER_MODE
#include <math.h>
#endif
#ifdef OPENAIR2
#include "LAYER2/MAC/defs.h"
@@ -296,12 +294,10 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com
#ifdef USER_MODE
#ifdef DEBUG_PHY
write_output("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1);
write_output("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1);
write_output("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1);
#endif
#endif
return (1);
}
@@ -310,7 +306,6 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com
void lte_sync_time_free(void)
{
#ifdef USER_MODE
if (sync_corr_ue0) {
msg("Freeing sync_corr_ue (%p)...\n",sync_corr_ue0);
@@ -342,7 +337,6 @@ void lte_sync_time_free(void)
free(primary_synch2_time);
}
#endif
sync_corr_ue0 = NULL;
sync_corr_ue1 = NULL;
sync_corr_ue2 = NULL;
@@ -502,19 +496,19 @@ int lte_sync_time(int **rxdata, ///rx data in time domain
sync_source,peak_pos,peak_val);
#ifdef USER_MODE
if (debug_cnt == 5) {
if (debug_cnt == 0) {
write_output("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2);
write_output("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2);
write_output("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2);
write_output("rxdata0.m","rxd0",rxdata[0],length<<1,1,1);
exit(-1);
// exit(-1);
} else {
debug_cnt++;
}
#endif
#endif
@@ -574,11 +568,8 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
//calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
//#ifndef USER_MODE
result = dot_product((short*)primary_synch_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, 15);
//#else
// result = dot_product((short*)primary_synch_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples, 12);
//#endif
//((short*)sync_corr)[2*n] += ((short*) &result)[0];
//((short*)sync_corr)[2*n+1] += ((short*) &result)[1];
sync_corr_eNB[n] += abs32(result);
@@ -46,14 +46,15 @@
//#include "defs.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#if defined(__x86_64__) || defined(__i386__)
#include "pss6144.h"
extern void print_shorts(char*,__m128i*);
#endif
void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq)
{
#if defined(__x86_64__) || defined(__i386__)
UE_SCAN_INFO_t *scan_info = &ue->scan_info[band];
int16_t spectrum[12288] __attribute__((aligned(16)));
int16_t spectrum_p5ms[12288] __attribute__((aligned(16)));
@@ -358,5 +359,6 @@ void lte_sync_timefreq(PHY_VARS_UE *ue,int band,unsigned int DL_freq)
for (band_idx=0; band_idx<10; band_idx++)
printf("pss 2: level %d dB, freq %u\n", dB_fixed(scan_info->amp[2][band_idx]),scan_info->freq_offset_Hz[2][band_idx]);
#endif
}
+105 -120
View File
@@ -42,39 +42,32 @@
//#define DEBUG_MEAS
#ifdef USER_MODE
void print_shorts(char *s,__m128i *x)
void print_shorts(char *s,short *x)
{
short *tempb = (short *)x;
printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,
tempb[0],tempb[1],tempb[2],tempb[3],tempb[4],tempb[5],tempb[6],tempb[7]
x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7]
);
}
void print_ints(char *s,__m128i *x)
void print_ints(char *s,int *x)
{
int *tempb = (int *)x;
printf("%s : %d,%d,%d,%d\n",s,
tempb[0],tempb[1],tempb[2],tempb[3]
x[0],x[1],x[2],x[3]
);
}
#endif
__m128i pmi128_re __attribute__ ((aligned(16)));
__m128i pmi128_im __attribute__ ((aligned(16)));
__m128i mmtmpPMI0 __attribute__ ((aligned(16)));
__m128i mmtmpPMI1 __attribute__ ((aligned(16)));
__m128i mmtmpPMI2 __attribute__ ((aligned(16)));
__m128i mmtmpPMI3 __attribute__ ((aligned(16)));
int16_t get_PL(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
/*
int RSoffset;
@@ -82,7 +75,7 @@ int16_t get_PL(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
RSoffset = 6;
else
RSoffset = 3;
*/
LOG_D(PHY,"get_PL : Frame %d : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", phy_vars_ue->frame_rx,
(1.0*dB_fixed_times10(phy_vars_ue->PHY_measurements.rsrp[eNB_index])-(10.0*phy_vars_ue->rx_total_gain_dB))/10.0,
@@ -204,47 +197,83 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
if (phy_vars_ue->lte_frame_parms.Ncp==NORMAL) {
for (aarx=0; aarx<phy_vars_ue->lte_frame_parms.nb_antennas_rx; aarx++) {
rxF_sss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(5*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
rxF_pss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(6*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
rxF_sss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(5*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
rxF_pss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(6*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
//-ve spectrum from SSS
phy_vars_ue->PHY_measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
// printf("slot %d: SSS DTX: %d,%d, non-DTX %d,%d\n",slot,rxF_pss[-72],rxF_pss[-71],rxF_pss[-36],rxF_pss[-35]);
// phy_vars_ue->PHY_measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
// printf("sssn36 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]);
phy_vars_ue->PHY_measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
// printf("sssm32 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]);
//+ve spectrum from SSS
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+72]*rxF_sss[2+72])+((int32_t)rxF_sss[2+71]*rxF_sss[2+71]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
// printf("sssp32 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]);
//+ve spectrum from PSS
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+72]*rxF_pss[2+72])+((int32_t)rxF_pss[2+71]*rxF_pss[2+71]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
//-ve spectrum from PSS
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
// printf("pss32 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]); //-ve spectrum from PSS
rxF_pss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(7*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
// printf("pssm36 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]);
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]/10);
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
// printf("pssm32 %d\n",phy_vars_ue->PHY_measurements.n0_power[aarx]);
phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]/12);
phy_vars_ue->PHY_measurements.n0_power_tot += phy_vars_ue->PHY_measurements.n0_power[aarx];
}
phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/20);
phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB;
}
phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/(12*aarx));
phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB - dB_fixed(phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
}
}
else if ((phy_vars_ue->lte_frame_parms.frame_type == TDD) &&
(slot == 1)) { // TDD SSS, compute noise in DTX REs
if (phy_vars_ue->lte_frame_parms.Ncp==NORMAL) {
for (aarx=0; aarx<phy_vars_ue->lte_frame_parms.nb_antennas_rx; aarx++) {
rxF_sss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(6*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
// note this is a dummy pointer, the pss is not really there!
// in FDD the pss is in the symbol after the sss, but not in TDD
rxF_pss = (int16_t *)&phy_vars_ue->lte_ue_common_vars.rxdataF[aarx][(7*phy_vars_ue->lte_frame_parms.ofdm_symbol_size)];
//-ve spectrum from SSS
// phy_vars_ue->PHY_measurements.n0_power[aarx] = (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
phy_vars_ue->PHY_measurements.n0_power[aarx] = (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
//+ve spectrum from SSS
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+72]*rxF_sss[2+72])+((int32_t)rxF_sss[2+71]*rxF_sss[2+71]));
phy_vars_ue->PHY_measurements.n0_power[aarx] = (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
// phy_vars_ue->PHY_measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]/(6));
phy_vars_ue->PHY_measurements.n0_power_tot += phy_vars_ue->PHY_measurements.n0_power[aarx];
}
phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot/(6*aarx));
phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB - dB_fixed(phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
}
}
}
}
// recompute nushift with eNB_offset corresponding to adjacent eNB on which to perform channel estimation
// printf("[PHY][UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, Nid2 %d, nushift %d, eNB_offset %d)\n",phy_vars_ue->Mod_id,phy_vars_ue->frame,slot,Nid_cell,Nid2,nushift,eNB_offset);
if (eNB_offset > 0)
@@ -265,7 +294,7 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
for (l=0,nu=0; l<=(4-phy_vars_ue->lte_frame_parms.Ncp); l+=(4-phy_vars_ue->lte_frame_parms.Ncp),nu=3) {
k = (nu + nushift)%6;
#ifdef DEBUG_MEAS
LOG_D(PHY,"[UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",phy_vars_ue->Mod_id,phy_vars_ue->frame_rx,slot,Nid_cell,nushift,
LOG_I(PHY,"[UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",phy_vars_ue->Mod_id,phy_vars_ue->frame_rx,slot,Nid_cell,nushift,
eNB_offset,k,l);
#endif
@@ -280,10 +309,10 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
phy_vars_ue->PHY_measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
// printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
/* if ((phy_vars_ue->frame_rx&0x3ff) == 0)
printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
// if ((phy_vars_ue->frame_rx&0x3ff) == 0)
// printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
*/
off+=12;
if (off>=(phy_vars_ue->lte_frame_parms.ofdm_symbol_size<<1))
@@ -317,13 +346,10 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
}
}
// 2 RE per PRB
// phy_vars_ue->PHY_measurements.rsrp[eNB_offset]/=(24*phy_vars_ue->lte_frame_parms.N_RB_DL);
phy_vars_ue->PHY_measurements.rsrp[eNB_offset]/=(2*phy_vars_ue->lte_frame_parms.N_RB_DL*phy_vars_ue->lte_frame_parms.ofdm_symbol_size);
LOG_D(PHY,"eNB: %d, RSRP: %d \n",eNB_offset,phy_vars_ue->PHY_measurements.rsrp[eNB_offset]);
// LOG_I(PHY,"eNB: %d, RSRP: %d \n",eNB_offset,phy_vars_ue->PHY_measurements.rsrp[eNB_offset]);
if (eNB_offset == 0) {
// phy_vars_ue->PHY_measurements.rssi/=(24*phy_vars_ue->lte_frame_parms.N_RB_DL);
// phy_vars_ue->PHY_measurements.rssi*=rx_power_correction;
@@ -347,16 +373,16 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
#ifdef DEBUG_MEAS
if (slot == 0) {
// if (slot == 0) {
if (eNB_offset == 0)
LOG_D(PHY,"[UE %d] Frame %d, slot %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",phy_vars_ue->Mod_id,
LOG_I(PHY,"[UE %d] Frame %d, slot %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",phy_vars_ue->Mod_id,
phy_vars_ue->frame_rx,slot,10*log10(phy_vars_ue->PHY_measurements.rssi)-phy_vars_ue->rx_total_gain_dB,
10*log10(phy_vars_ue->PHY_measurements.rssi),
phy_vars_ue->rx_total_gain_dB,
phy_vars_ue->PHY_measurements.n0_power_tot_dBm);
LOG_D(PHY,"[UE %d] Frame %d, slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d), rsrq: %3.1f dB\n",
LOG_I(PHY,"[UE %d] Frame %d, slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d), rsrq: %3.1f dB\n",
phy_vars_ue->Mod_id,
phy_vars_ue->frame_rx,slot,eNB_offset,
(eNB_offset>0) ? phy_vars_ue->PHY_measurements.adj_cell_id[eNB_offset-1] : phy_vars_ue->lte_frame_parms.Nid_cell,
@@ -369,7 +395,7 @@ void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
//LOG_D(PHY,"gain_loss_dB: %d \n",phy_vars_ue->rx_total_gain_dB);
//LOG_D(PHY,"gain_fixed_dB: %d \n",dB_fixed(phy_vars_ue->lte_frame_parms.N_RB_DL*12));
}
// }
#endif
}
@@ -383,11 +409,15 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
{
int aarx,aatx,eNB_id=0,gain_offset=0;
int aarx,aatx,eNB_id=0; //,gain_offset=0;
//int rx_power[NUMBER_OF_CONNECTED_eNB_MAX];
int i;
unsigned int limit,subband;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch0_128,*dl_ch1_128;
#elif defined(__arm__)
int16x8_t *dl_ch0_128, *dl_ch1_128;
#endif
int *dl_ch0,*dl_ch1;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
int nb_subbands,subband_size,last_subband_size;
@@ -420,37 +450,6 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
break;
}
/* // DONE NOW in ue_rrc_measurements
if (abstraction_flag!=0) {
phy_vars_ue->PHY_measurements.n0_power_tot = 0;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
phy_vars_ue->PHY_measurements.n0_power[aarx] = pow(10.0,phy_vars_ue->N0/10.0)*pow(10.0,((double)phy_vars_ue->rx_total_gain_dB)/10.0);
phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]);
phy_vars_ue->PHY_measurements.n0_power_tot += phy_vars_ue->PHY_measurements.n0_power[aarx];
}
phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot);
phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB;
}
else if (N0_symbol != 0) {
phy_vars_ue->PHY_measurements.n0_power_tot = 0;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#ifndef HW_PREFIX_REMOVAL
phy_vars_ue->PHY_measurements.n0_power[aarx] = signal_energy(&phy_vars_ue->lte_ue_common_vars.rxdata[aarx][subframe_offset+frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0],frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
#else
phy_vars_ue->PHY_measurements.n0_power[aarx] = signal_energy(&phy_vars_ue->lte_ue_common_vars.rxdata[aarx][subframe_offset+frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size);
#endif
phy_vars_ue->PHY_measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power[aarx]);
phy_vars_ue->PHY_measurements.n0_power_tot += phy_vars_ue->PHY_measurements.n0_power[aarx];
}
phy_vars_ue->PHY_measurements.n0_power_tot_dB = (unsigned short) dB_fixed(phy_vars_ue->PHY_measurements.n0_power_tot);
phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB + gain_offset;
// printf("PHY measurements UE %d: n0_power %d (%d)\n",phy_vars_ue->Mod_id,phy_vars_ue->PHY_measurements.n0_power_tot_dBm,phy_vars_ue->PHY_measurements.n0_power_tot_dB);
}
else {
phy_vars_ue->PHY_measurements.n0_power_tot_dBm = phy_vars_ue->PHY_measurements.n0_power_tot_dB - phy_vars_ue->rx_total_gain_dB + gain_offset;
}
*/
// signal measurements
for (eNB_id=0; eNB_id<phy_vars_ue->n_connected_eNB; eNB_id++) {
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -507,7 +506,7 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
phy_vars_ue->PHY_measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(phy_vars_ue->PHY_measurements.rx_power_avg[eNB_id],phy_vars_ue->PHY_measurements.n0_power_avg);
phy_vars_ue->PHY_measurements.rx_rssi_dBm[eNB_id] = phy_vars_ue->PHY_measurements.rx_power_avg_dB[eNB_id] - phy_vars_ue->rx_total_gain_dB;
#ifdef DEBUG_MEAS
LOG_D(PHY,"[eNB %d] lte_ue_measurements: RSSI %d dBm, RSSI (digital) %d dB\n",
LOG_I(PHY,"[eNB %d] lte_ue_measurements: RSSI %d dBm, RSSI (digital) %d dB\n",
eNB_id,phy_vars_ue->PHY_measurements.rx_rssi_dBm[eNB_id],
phy_vars_ue->PHY_measurements.rx_power_avg_dB[eNB_id]);
#endif
@@ -571,26 +570,30 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
// skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit)
#if defined(__x86_64__) || defined(__i386__)
__m128i pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI2,mmtmpPMI3;
dl_ch0_128 = (__m128i *)&phy_vars_ue->lte_ue_common_vars.dl_ch_estimates[eNB_id][aarx][4];
dl_ch1_128 = (__m128i *)&phy_vars_ue->lte_ue_common_vars.dl_ch_estimates[eNB_id][2+aarx][4];
#elif defined(__arm__)
int32x4_t pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI0b,mmtmpPMI1b;
/*
#ifdef DEBUG_PHY
if(eNB_id==0){
print_shorts("Ch0",dl_ch0_128);
print_shorts("Ch1",dl_ch1_128);
printf("eNB_ID = %d\n",eNB_id);
}
#endif
*/
dl_ch0_128 = (int16x8_t *)&phy_vars_ue->lte_ue_common_vars.dl_ch_estimates[eNB_id][aarx][4];
dl_ch1_128 = (int16x8_t *)&phy_vars_ue->lte_ue_common_vars.dl_ch_estimates[eNB_id][2+aarx][4];
#endif
for (subband=0; subband<nb_subbands; subband++) {
// pmi
#if defined(__x86_64__) || defined(__i386__)
pmi128_re = _mm_setzero_si128();
pmi128_im = _mm_setzero_si128();
#elif defined(__arm__)
pmi128_re = vdupq_n_s32(0);
pmi128_im = vdupq_n_s32(0);
#endif
// limit is the number of groups of 4 REs in a subband (12 = 4 RBs, 3 = 1 RB)
// for 5 MHz channelization, there are 7 subbands, 6 of size 4 RBs and 1 of size 1 RB
if ((N_RB_DL==6) || (subband<(nb_subbands-1)))
@@ -602,52 +605,33 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
// For each RE in subband perform ch0 * conj(ch1)
// multiply by conjugated channel
// if(eNB_id==0){
//print_shorts("ch0",dl_ch0_128);
//print_shorts("ch1",dl_ch1_128);
// }
// if(i==0){
mmtmpPMI0 = _mm_setzero_si128();
mmtmpPMI1 = _mm_setzero_si128();
// }
// if(eNB_id==0)
// print_ints("Pre_re",&mmtmpPMI0);
mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
// if(eNB_id==0)
// print_ints("re",&mmtmpPMI0);
// mmtmpPMI0 contains real part of 4 consecutive outputs (32-bit)
// print_shorts("Ch1",dl_ch1_128);
#if defined(__x86_64__) || defined(__i386__)
mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1));//_MM_SHUFFLE(2,3,0,1)
// print_shorts("mmtmpPMI1:",&mmtmpPMI1);
mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
// print_shorts("mmtmpPMI1:",&mmtmpPMI1);
mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]);
// print_shorts("mmtmpPMI1:",&mmtmpPMI1);
mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]);
// if(eNB_id==0)
// print_ints("im",&mmtmpPMI1);
// mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
#elif defined(__arm__)
mmtmpPMI0 = vmull_s16(((int16x4_t*)dl_ch0_128)[0], ((int16x4_t*)dl_ch1_128)[0]);
mmtmpPMI1 = vmull_s16(((int16x4_t*)dl_ch0_128)[1], ((int16x4_t*)dl_ch1_128)[1]);
pmi128_re = vqaddq_s32(pmi128_re,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0),vget_high_s32(mmtmpPMI0)),vpadd_s32(vget_low_s32(mmtmpPMI1),vget_high_s32(mmtmpPMI1))));
mmtmpPMI0b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[0]);
mmtmpPMI1b = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)dl_ch0_128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)dl_ch1_128)[1]);
pmi128_im = vqaddq_s32(pmi128_im,vcombine_s32(vpadd_s32(vget_low_s32(mmtmpPMI0b),vget_high_s32(mmtmpPMI0b)),vpadd_s32(vget_low_s32(mmtmpPMI1b),vget_high_s32(mmtmpPMI1b))));
#endif
dl_ch0_128++;
dl_ch1_128++;
}
phy_vars_ue->PHY_measurements.subband_pmi_re[eNB_id][subband][aarx] = (((int *)&pmi128_re)[0] + ((int *)&pmi128_re)[1] + ((int *)&pmi128_re)[2] + ((int *)&pmi128_re)[3])>>2;
// if(eNB_id==0)
// printf("in lte_ue_measurements.c: pmi_re %d\n",phy_vars_ue->PHY_measurements.subband_pmi_re[eNB_id][subband][aarx]);
phy_vars_ue->PHY_measurements.subband_pmi_im[eNB_id][subband][aarx] = (((int *)&pmi128_im)[0] + ((int *)&pmi128_im)[1] + ((int *)&pmi128_im)[2] + ((int *)&pmi128_im)[3])>>2;
// if(eNB_id==0)
// printf("in lte_ue_measurements.c: pmi_im %d\n",phy_vars_ue->PHY_measurements.subband_pmi_im[eNB_id][subband][aarx]);
phy_vars_ue->PHY_measurements.wideband_pmi_re[eNB_id][aarx] += phy_vars_ue->PHY_measurements.subband_pmi_re[eNB_id][subband][aarx];
phy_vars_ue->PHY_measurements.wideband_pmi_im[eNB_id][aarx] += phy_vars_ue->PHY_measurements.subband_pmi_im[eNB_id][subband][aarx];
// msg("subband_pmi[%d][%d][%d] => (%d,%d)\n",eNB_id,subband,aarx,phy_vars_ue->PHY_measurements.subband_pmi_re[eNB_id][subband][aarx],phy_vars_ue->PHY_measurements.subband_pmi_im[eNB_id][subband][aarx]);
} // subband loop
} // rx antenna loop
} // if frame_parms->mode1_flag == 0
@@ -708,9 +692,10 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
// printf("in lte_ue_measurements: selected rx_antenna[eNB_id==0]:%u\n", phy_vars_ue->PHY_measurements.selected_rx_antennas[eNB_id][i]);
} // eNB_id loop
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
@@ -106,9 +106,13 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
*temp_out_fft_1_ptr = (int32_t*)0,*out_fft_ptr_1 = (int32_t*)0,
*temp_in_ifft_ptr = (int32_t*)0;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF128,*ul_ref128,*ul_ch128;
__m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
#elif defined(__arm__)
int16x8_t *rxdataF128,*ul_ref128,*ul_ch128;
int32x4_t mmtmp0,mmtmp1,mmtmp_re,mmtmp_im;
#endif
Msc_RS = N_rb_alloc*12;
cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
@@ -156,11 +160,18 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
for (aa=0; aa<nb_antennas_rx; aa++) {
// msg("Componentwise prod aa %d, symbol_offset %d,ul_ch_estimates %p,ul_ch_estimates[aa] %p,ul_ref_sigs_rx[0][0][Msc_RS_idx] %p\n",aa,symbol_offset,ul_ch_estimates,ul_ch_estimates[aa],ul_ref_sigs_rx[0][0][Msc_RS_idx]);
#if defined(__x86_64__) || defined(__i386__)
rxdataF128 = (__m128i *)&rxdataF_ext[aa][symbol_offset];
ul_ch128 = (__m128i *)&ul_ch_estimates[aa][symbol_offset];
ul_ref128 = (__m128i *)ul_ref_sigs_rx[u][v][Msc_RS_idx];
#elif defined(__arm__)
rxdataF128 = (int16x8_t *)&rxdataF_ext[aa][symbol_offset];
ul_ch128 = (int16x8_t *)&ul_ch_estimates[aa][symbol_offset];
ul_ref128 = (int16x8_t *)ul_ref_sigs_rx[u][v][Msc_RS_idx];
#endif
for (i=0; i<Msc_RS/12; i++) {
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ref128[0],rxdataF128[0]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
@@ -204,7 +215,50 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
ul_ch128[2] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
#elif defined(__arm__)
mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
ul_ch128++;
ul_ref128++;
rxdataF128++;
mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
ul_ch128++;
ul_ref128++;
rxdataF128++;
mmtmp0 = vmull_s16(((int16x4_t*)ul_ref128)[0],((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(((int16x4_t*)ul_ref128)[1],((int16x4_t*)rxdataF128)[1]);
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[0],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[0]);
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)ul_ref128)[1],*(int16x4_t*)conjugate)), ((int16x4_t*)rxdataF128)[1]);
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
ul_ch128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
ul_ch128++;
ul_ref128++;
rxdataF128++;
#endif
ul_ch128+=3;
ul_ref128+=3;
rxdataF128+=3;
@@ -538,17 +592,17 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
// msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]);
// rotate channel estimates by estimated phase
rotate_cpx_vector_norep((int16_t*) ul_ch1,
&ru1[2*current_phase1],
(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],
Msc_RS,
15);
rotate_cpx_vector((int16_t*) ul_ch1,
&ru1[2*current_phase1],
(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],
Msc_RS,
15);
rotate_cpx_vector_norep((int16_t*) ul_ch2,
&ru2[2*current_phase2],
(int16_t*) &tmp_estimates[0],
Msc_RS,
15);
rotate_cpx_vector((int16_t*) ul_ch2,
&ru2[2*current_phase2],
(int16_t*) &tmp_estimates[0],
Msc_RS,
15);
// Combine the two rotated estimates
multadd_complex_vector_real_scalar((int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],SCALE,(int16_t*) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k],1,Msc_RS);
@@ -664,11 +718,11 @@ int32_t lte_srs_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
//write_output("eNb_rxF.m","rxF",&eNb_common_vars->rxdataF[0][aa][2*frame_parms->ofdm_symbol_size*symbol],2*(frame_parms->ofdm_symbol_size),2,1);
//write_output("eNb_srs.m","srs_eNb",eNb_common_vars->srs,(frame_parms->ofdm_symbol_size),1,1);
mult_cpx_vector_norep((int16_t*) &eNb_common_vars->rxdataF[eNb_id][aa][2*frame_parms->ofdm_symbol_size*symbol],
(int16_t*) eNb_srs_vars->srs,
(int16_t*) eNb_srs_vars->srs_ch_estimates[eNb_id][aa],
frame_parms->ofdm_symbol_size,
15);
mult_cpx_conj_vector((int16_t*) &eNb_common_vars->rxdataF[eNb_id][aa][2*frame_parms->ofdm_symbol_size*symbol],
(int16_t*) eNb_srs_vars->srs,
(int16_t*) eNb_srs_vars->srs_ch_estimates[eNb_id][aa],
frame_parms->ofdm_symbol_size,
15);
//msg("SRS channel estimation cmult out\n");
#ifdef USER_MODE
@@ -695,6 +749,7 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb)
{
#if defined(__x86_64__) || defined(__i386__)
int k, rb;
int a_idx = 64;
uint8_t conj_flag = 0;
@@ -830,4 +885,7 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms,
phase_idx = -phase_idx;
return(phase_idx);
#elif defined(__arm__)
return(0);
#endif
}
+2 -2
View File
@@ -94,9 +94,9 @@ int lte_dl_cell_spec_SS(PHY_VARS_eNB *phy_vars_eNB,
output[k] = qpsk[(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3];
//output[k] = (lte_gold_table[eNB_offset][Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3;
#ifdef DEBUG_DL_CELL_SPEC
debug_msg("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n",
msg("Ns %d, l %d, m %d,mprime_dword %d, mprime_qpsk_symbol %d\n",
Ns,l,m,mprime_dword,mprime_qpsk_symb);
debug_msg("index = %d (k %d)\n",(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k);
msg("index = %d (k %d)\n",(phy_vars_eNB->lte_gold_table[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k);
#endif
mprime++;
+269 -111
View File
@@ -86,7 +86,7 @@ uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t
(mprime == pcfich_reg[2]) ||
(mprime == pcfich_reg[3]))) {
#ifdef DEBUG_DCI_ENCODING
msg("[PHY] REG %d allocated to PCFICH\n",mprime);
printf("[PHY] REG %d allocated to PCFICH\n",mprime);
#endif
return(1);
}
@@ -109,7 +109,7 @@ uint32_t check_phich_reg(LTE_DL_FRAME_PARMS *frame_parms,uint32_t kprime,uint8_t
(mprime == frame_parms->phich_reg[i][1]) ||
(mprime == frame_parms->phich_reg[i][2])) {
#ifdef DEBUG_DCI_ENCODING
msg("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime);
printf("[PHY] REG %d (lprime %d) allocated to PHICH\n",mprime,lprime);
#endif
return(1);
}
@@ -139,7 +139,7 @@ uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
printf("extract_crc: crc %x\n",crc);
*/
#ifdef DEBUG_DCI_DECODING
msg("dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)],
LOG_I(PHY,"dci_crc (%x,%x,%x), dci_len&0x7=%d\n",dci[dci_len>>3],dci[1+(dci_len>>3)],dci[2+(dci_len>>3)],
dci_len&0x7);
#endif
@@ -152,7 +152,7 @@ uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
}
#ifdef DEBUG_DCI_DECODING
msg("dci_crc =>%x\n",crc16);
LOG_I(PHY,"dci_crc =>%x\n",crc16);
#endif
// dci[(dci_len>>3)]&=(0xffff<<(dci_len&0xf));
@@ -184,7 +184,7 @@ void dci_encoding(uint8_t *a,
// encode dci
#ifdef DEBUG_DCI_ENCODING
msg("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti);
printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti);
#endif
memset((void *)d,LTE_NULL,96);
@@ -194,17 +194,17 @@ void dci_encoding(uint8_t *a,
#ifdef DEBUG_DCI_ENCODING
for (i=0; i<16+A; i++)
msg("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
#endif
#ifdef DEBUG_DCI_ENCODING
msg("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
#endif
RCC = sub_block_interleaving_cc(D,d+96,w);
#ifdef DEBUG_DCI_ENCODING
msg("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
#endif
lte_rate_matching_cc(RCC,E,w,e);
@@ -223,7 +223,7 @@ uint8_t *generate_dci0(uint8_t *dci,
uint8_t dci_flip[8];
if (aggregation_level>3) {
msg("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
printf("dci.c: generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level);
return NULL;
}
@@ -233,7 +233,7 @@ uint8_t *generate_dci0(uint8_t *dci,
#ifdef DEBUG_DCI_ENCODING
for (i=0;i<1+((DCI_LENGTH+16)/8);i++)
msg("i %d : %x\n",i,dci[i]);
printf("i %d : %x\n",i,dci[i]);
#endif
*/
if (DCI_LENGTH<=32) {
@@ -251,7 +251,7 @@ uint8_t *generate_dci0(uint8_t *dci,
dci_flip[6] = dci[1];
dci_flip[7] = dci[0];
#ifdef DEBUG_DCI_ENCODING
msg("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
#endif
@@ -286,7 +286,7 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,mod_sym_t **z, mod_sym_t
int32_t nulled=0;
#endif
// msg("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
// printf("[PHY] PDCCH Interleaving Mquad %d (Nsymb %d)\n",Mquad,n_symbols_pdcch);
if ((Mquad&0x1f) > 0)
RCC++;
@@ -299,15 +299,15 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,mod_sym_t **z, mod_sym_t
index = bitrev_cc_dci[col];
for (row=0; row<RCC; row++) {
//msg("col %d, index %d, row %d\n",col,index,row);
//printf("col %d, index %d, row %d\n",col,index,row);
if (index>=ND) {
for (a=0; a<frame_parms->nb_antennas_tx_eNB; a++) {
//msg("a %d k %d\n",a,k);
//printf("a %d k %d\n",a,k);
wptr = &wtemp[a][k<<2];
zptr = &z[a][(index-ND)<<2];
//msg("wptr=%p, zptr=%p\n",wptr,zptr);
//printf("wptr=%p, zptr=%p\n",wptr,zptr);
wptr[0] = zptr[0];
wptr[1] = zptr[1];
@@ -396,11 +396,11 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
// if REG is allocated to PHICH, skip it
if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
//msg("dci_demapping : skipping REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
if ((lprime == 0)&&((kprime%6)==0))
re_offset0+=4;
// printf("dci_demapping : skipping REG %d (RE %d)\n",(lprime==0)?kprime/6 : kprime>>2,kprime);
if ((lprime == 0)&&((kprime%6)==0))
re_offset0+=4;
} else { // not allocated to PHICH/PCFICH
// msg("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
// printf("dci_demapping: REG %d\n",(lprime==0)?kprime/6 : kprime>>2);
if (lprime == 0) {
// first symbol, or second symbol+4 TX antennas skip pilots
kprime_mod12 = kprime%12;
@@ -411,7 +411,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
for (i=0; i<4; i++) {
wbar[mprime] = llr[tti_offset0+i];
#ifdef DEBUG_DCI_DECODING
msg("[PHY] PDCCH demapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset0,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
#endif
mprime++;
re_offset0++;
@@ -427,7 +427,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
for (i=0; i<4; i++) {
wbar[mprime] = llr[tti_offset+i];
#ifdef DEBUG_DCI_DECODING
msg("[PHY] PDCCH demapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
#endif
mprime++;
}
@@ -460,14 +460,12 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t
// printf("Mquad %d, RCC %d\n",Mquad,RCC);
if (!z) {
msg("dci.c: pdcch_deinterleaving: FATAL z is Null\n");
printf("dci.c: pdcch_deinterleaving: FATAL z is Null\n");
return;
}
// undo permutation
for (i=0; i<Mquad; i++) {
//wptr = &wtemp_rx[i<<2];
//wptr2 = &wbar[((i+frame_parms->Nid_cell)%Mquad)<<2];
wptr = &wtemp_rx[((i+frame_parms->Nid_cell)%Mquad)<<2];
wptr2 = &wbar[i<<2];
@@ -475,16 +473,16 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t
wptr[1] = wptr2[1];
wptr[2] = wptr2[2];
wptr[3] = wptr2[3];
/*
msg("pdcch_deinterleaving (%p,%p): quad %d -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,
((char*)wptr2)[0],
((char*)wptr2)[1],
((char*)wptr2)[2],
((char*)wptr2)[3],
((char*)wptr2)[4],
((char*)wptr2)[5],
((char*)wptr2)[6],
((char*)wptr2)[7]);
/*
printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad,
((char*)wptr2)[0],
((char*)wptr2)[1],
((char*)wptr2)[2],
((char*)wptr2)[3],
((char*)wptr2)[4],
((char*)wptr2)[5],
((char*)wptr2)[6],
((char*)wptr2)[7]);
*/
}
@@ -514,7 +512,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t
zptr[2] = wptr[2];
zptr[3] = wptr[3];
/*
/*
printf("deinterleaving ; k %d, index-Nd %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND),
((int8_t *)wptr)[0],
((int8_t *)wptr)[1],
@@ -524,7 +522,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t
((int8_t *)wptr)[5],
((int8_t *)wptr)[6],
((int8_t *)wptr)[7]);
*/
*/
k++;
}
@@ -535,7 +533,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t
for (i=0; i<Mquad; i++) {
zptr = &z[i<<2];
/*
/*
printf("deinterleaving ; quad %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i,
((int8_t *)zptr)[0],
((int8_t *)zptr)[1],
@@ -545,7 +543,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t
((int8_t *)zptr)[5],
((int8_t *)zptr)[6],
((int8_t *)zptr)[7]);
*/
*/
}
}
@@ -560,10 +558,10 @@ int32_t pdcch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t symbol)
{
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *rxF_i=(__m128i*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *rho=(__m128i*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *llr128;
int16_t *rxF=(int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int16_t *rxF_i=(int16_t*)&rxdataF_comp_i[0][(symbol*frame_parms->N_RB_DL*12)];
int16_t *rho=(int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
int16_t *llr128;
int32_t i;
char *pdcch_llr8;
int16_t *pdcch_llr;
@@ -572,17 +570,17 @@ int32_t pdcch_qpsk_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
// printf("dlsch_qpsk_qpsk: symbol %d\n",symbol);
llr128 = (__m128i*)pdcch_llr;
llr128 = (int16_t*)pdcch_llr;
if (!llr128) {
msg("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
printf("dlsch_qpsk_qpsk_llr: llr is null, symbol %d\n",symbol);
return -1;
}
qpsk_qpsk((int16_t *)rxF,
(int16_t *)rxF_i,
(int16_t *)llr128,
(int16_t *)rho,
qpsk_qpsk(rxF,
rxF_i,
llr128,
rho,
frame_parms->N_RB_DL*12);
//prepare for Viterbi which accepts 8 bit, but prefers 4 bit, soft input.
@@ -615,11 +613,11 @@ int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms,
pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12];
if (!pdcch_llr8) {
msg("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol);
return(-1);
}
// msg("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr);
// printf("pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llr8-pdcch_llr);
for (i=0; i<(frame_parms->N_RB_DL*((symbol==0) ? 16 : 24)); i++) {
@@ -639,7 +637,7 @@ int32_t pdcch_llr(LTE_DL_FRAME_PARMS *frame_parms,
}
__m128i avg128P;
//__m128i avg128P;
//compute average channel_level on each (TX,RX) antenna pair
void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
@@ -650,21 +648,31 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
int16_t rb;
uint8_t aatx,aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128;
__m128i avg128P;
#elif defined(__arm__)
int16x8_t *dl_ch128;
int32x4_t *avg128P;
#endif
for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++)
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128P = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12];
#elif defined(__arm__)
#endif
for (rb=0; rb<nb_rb; rb++) {
#if defined(__x86_64__) || defined(__i386__)
avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__)
#endif
dl_ch128+=3;
/*
if (rb==0) {
@@ -675,21 +683,27 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
*/
}
DevAssert( nb_rb );
avg[(aatx<<1)+aarx] = (((int32_t*)&avg128P)[0] +
((int32_t*)&avg128P)[1] +
((int32_t*)&avg128P)[2] +
((int32_t*)&avg128P)[3])/(nb_rb*12);
// msg("Channel level : %d\n",avg[(aatx<<1)+aarx]);
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
#if defined(__x86_64) || defined(__i386__)
__m128i mmtmpPD0,mmtmpPD1,mmtmpPD2,mmtmpPD3;
#elif defined(__arm__)
#endif
void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t symbol,
int32_t **dl_ch_estimates_ext,
@@ -699,7 +713,11 @@ void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
{
uint16_t rb;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128;
#elif defined(__arm__)
#endif
uint8_t aarx;
// printf("dlsch_dual_stream_correlation: symbol %d\n",symbol);
@@ -707,13 +725,18 @@ void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128i = (__m128i *)&dl_ch_estimates_ext_i[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch_rho128 = (__m128i *)&dl_ch_rho_ext[aarx][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
#endif
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
// multiply by conjugated channel
#if defined(__x86_64__) || defined(__i386__)
mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128i[0]);
// print_ints("re",&mmtmpPD0);
@@ -778,13 +801,16 @@ void pdcch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
dl_ch128i+=3;
dl_ch_rho128+=3;
}
#elif defined(__arm__)
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
@@ -799,44 +825,78 @@ void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t aatx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
#elif defined(__arm__)
int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1;
#endif
int32_t i;
if (frame_parms->nb_antennas_rx>1) {
for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
//if (frame_parms->mode1_flag && (aatx>0)) break;
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
#endif
// MRC on each re of rb on MF output
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
#elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
rho128_0 = (int16x8_t *) &rho[0][symbol*frame_parms->N_RB_DL*12];
rho128_1 = (int16x8_t *) &rho[1][symbol*frame_parms->N_RB_DL*12];
#endif
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1));
#elif defined(__arm__)
rho128_0[i] = vhaddq_s16(rho128_0[i],rho128_1[i]);
#endif
}
#if defined(__x86_64__) || defined(__i386__)
rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
rho128_i0 = (int16x8_t*) &rho_i[0][symbol*frame_parms->N_RB_DL*12];
rho128_i1 = (int16x8_t*) &rho_i[1][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_i0 = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_i1 = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12];
#endif
// MRC on each re of rb on MF and rho
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1));
rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1));
#elif defined(__arm__)
rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]);
rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]);
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
@@ -860,7 +920,7 @@ void pdcch_extract_rbs_single(int32_t **rxdataF,
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#ifdef DEBUG_DCI_DECODING
msg("[PHY] extract_rbs_single: symbol_mod %d\n",symbol_mod);
LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod);
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -964,7 +1024,7 @@ void pdcch_extract_rbs_single(int32_t **rxdataF,
}
// Do middle RB (around DC)
// msg("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
// printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]);
if (symbol_mod==0) {
j=0;
@@ -1055,10 +1115,6 @@ void pdcch_extract_rbs_single(int32_t **rxdataF,
}
}
}
_mm_empty();
_m_empty();
}
void pdcch_extract_rbs_dual(int32_t **rxdataF,
@@ -1092,7 +1148,7 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
dl_ch1_ext = &dl_ch_estimates_ext[2+aarx][symbol*(frame_parms->N_RB_DL*12)];
// msg("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
// printf("pdcch extract_rbs: rxF_ext pos %d\n",symbol*(frame_parms->N_RB_DL*12));
rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)];
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))];
@@ -1112,14 +1168,14 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
/*
msg("rb %d\n",rb);
printf("rb %d\n",rb);
for (i=0;i<12;i++)
msg("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
msg("\n");
printf("(%d %d)",((int16_t *)dl_ch0)[i<<1],((int16_t*)dl_ch0)[1+(i<<1)]);
printf("\n");
*/
for (i=0; i<12; i++) {
rxF_ext[i]=rxF[i];
// msg("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
// printf("%d : (%d,%d)\n",(rxF+(2*i)-&rxdataF[aarx][( (symbol*(frame_parms->ofdm_symbol_size)))*2])/2,
// ((int16_t*)&rxF[i<<1])[0],((int16_t*)&rxF[i<<1])[0]);
}
@@ -1156,7 +1212,7 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
else { // Odd number of RBs
for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) {
// msg("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
// printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
if (symbol_mod>0) {
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
@@ -1267,7 +1323,7 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
for (; rb<frame_parms->N_RB_DL; rb++) {
if (symbol_mod>0) {
// msg("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
// printf("rb %d: %d\n",rb,rxF-&rxdataF[aarx][(symbol*(frame_parms->ofdm_symbol_size))*2]);
memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int32_t));
memcpy(dl_ch1_ext,dl_ch1,12*sizeof(int32_t));
@@ -1309,11 +1365,6 @@ void pdcch_extract_rbs_dual(int32_t **rxdataF,
}
}
}
_mm_empty();
_m_empty();
}
@@ -1327,15 +1378,19 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext,
{
uint16_t rb;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
__m128i *dl_ch128_2, *rho128;
#elif defined(__arm__)
#endif
uint8_t aatx,aarx,pilots=0;
#ifdef DEBUG_DCI_DECODING
msg("[PHY] PDCCH comp: symbol %d\n",symbol);
LOG_I(PHY, "PDCCH comp: symbol %d\n",symbol);
#endif
if (symbol==0)
@@ -1346,13 +1401,18 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
#endif
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpPD0);
@@ -1425,6 +1485,9 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext,
rxdataF128+=2;
rxdataF_comp128+=2;
}
#elif defined(__arm__)
#endif
}
}
}
@@ -1433,11 +1496,18 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext,
if (rho) {
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
#endif
for (rb=0; rb<frame_parms->N_RB_DL; rb++) {
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpPD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]);
// print_ints("re",&mmtmpD0);
@@ -1503,14 +1573,19 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext,
dl_ch128_2+=3;
rho128+=3;
#elif defined(__arm_)
#endif
}
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
@@ -1520,23 +1595,37 @@ void pdcch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t aatx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
#elif defined(__arm__)
int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1;
#endif
int32_t i;
if (frame_parms->nb_antennas_rx>1) {
for (aatx=0; aatx<frame_parms->nb_antennas_tx_eNB; aatx++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12];
#endif
// MRC on each re of rb
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
#elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
}
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
@@ -1592,8 +1681,6 @@ void pdcch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
}
}
_mm_empty();
_m_empty();
}
@@ -1667,9 +1754,9 @@ int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars,
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
avgs = cmax(avgs,avgP[(aarx<<1)+aatx]);
log2_maxh = (log2_approx(avgs)/2) + 2 + frame_parms->nb_antennas_rx - 1;
log2_maxh = (log2_approx(avgs)/2) + 6 + frame_parms->nb_antennas_rx - 1;
#ifdef DEBUG_PHY
msg("[PDCCH] log2_maxh = %d (%d,%d)\n",log2_maxh,avgP[0],avgs);
LOG_I(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs);
#endif
@@ -1785,10 +1872,11 @@ int32_t rx_pdcch(LTE_UE_COMMON *lte_ue_common_vars,
if (n_pdcch_symbols>3)
n_pdcch_symbols=1;
#ifdef DEBUG_DCI_DECODING
msg("[PDCCH] subframe %d n_pdcch_symbols from PCFICH =%d\n",subframe,n_pdcch_symbols);
msg("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
#ifdef DEBUG_DCI_DECODING
printf("[PDCCH] subframe %d n_pdcch_symbols from PCFICH =%d\n",subframe,n_pdcch_symbols);
printf("demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
#endif
pdcch_demapping(lte_ue_pdcch_vars[eNB_id]->llr,
@@ -1857,16 +1945,17 @@ void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2
for (i=0; i<length; i++) {
if (i%32==0) {
if ((i&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
//printf("lte_gold[%d]=%x\n",i,s);
// printf("lte_gold[%d]=%x\n",i,s);
reset = 0;
}
// take the quarter of the PBCH that corresponds to this frame
// printf("unscrambling %d : e %d, c %d\n",i,llr[i],((s>>(i&0x1f))&1));
// printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1));
if (((s>>(i%32))&1)==0)
llr[i] = -llr[i];
// printf("%d\n",llr[i]);
}
}
@@ -1924,7 +2013,7 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
}
msg("[PHY] dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
//for (i=0;i<num_dci;i++) {
// printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
//}
@@ -2004,10 +2093,10 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
y[1] = &yseq1[0];
// reset all bits to <NIL>, here we set <NIL> elements as 2
//memset(e, 2, DCI_BITS_MAX);
// here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
for (i=0; i<DCI_BITS_MAX; i++)
e[i]=taus()&1;
memset(e, 2, DCI_BITS_MAX);
// // here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
// for (i=0; i<DCI_BITS_MAX; i++)
// e[i]=2;//taus()&1;
e_ptr = e;
@@ -2084,7 +2173,6 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
//((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
e_ptr++;
//((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
//((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
@@ -2127,7 +2215,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
LOG_I(PHY," PDCCH Interleaving\n");
#endif
// msg("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
// printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
// This is the interleaving procedure defined in 36-211, first part of Section 6.8.5
pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi);
@@ -2152,7 +2240,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
// if REG is allocated to PHICH, skip it
if (check_phich_reg(frame_parms,kprime,lprime,mi) == 1) {
#ifdef DEBUG_DCI_ENCODING
msg("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime);
printf("generate_dci: skipping REG %d (kprime %d, lprime %d)\n",(lprime==0)?(kprime/6) : (kprime>>2),kprime,lprime);
#endif
} else {
// Copy REG to TX buffer
@@ -2389,15 +2477,15 @@ void dci_decoding(uint8_t DCI_LENGTH,
memset(decoded_output,0,2+((16+DCI_LENGTH)>>3));
#ifdef DEBUG_DCI_DECODING
msg("Before Viterbi\n");
printf("Before Viterbi\n");
for (i=0; i<16+DCI_LENGTH; i++)
msg("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
printf("%d : (%d,%d,%d)\n",i,*(d_rx+96+(3*i)),*(d_rx+97+(3*i)),*(d_rx+98+(3*i)));
#endif
//debug_msg("Doing DCI Viterbi \n");
//debug_printf("Doing DCI Viterbi \n");
phy_viterbi_lte_sse2(d_rx+96,decoded_output,16+DCI_LENGTH);
//debug_msg("Done DCI Viterbi \n");
//debug_printf("Done DCI Viterbi \n");
}
@@ -2456,7 +2544,9 @@ uint16_t get_nCCE_max(uint8_t Mod_id,uint8_t CC_id)
return(get_nCCE(3,&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,1)); // 5, 15,21
}
void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint8_t subframe,
void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,
int do_common,
uint8_t subframe,
DCI_ALLOC_t *dci_alloc,
int16_t eNB_id,
LTE_DL_FRAME_PARMS *frame_parms,
@@ -2542,6 +2632,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint
else {
LOG_E(PHY,"Illegal CCEind %d (Yk %d, m %d, nCCE %d, L2 %d\n",CCEind,Yk,m,nCCE,L2);
mac_xface->macphy_exit("Illegal CCEind\n");
return; // not reached
}
switch (L2) {
@@ -2560,6 +2651,11 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint
case 8:
CCEmap_mask = (0xff<<(CCEind&0x1f));
break;
default:
LOG_E( PHY, "Illegal L2 value %d\n", L2 );
mac_xface->macphy_exit( "Illegal L2\n" );
return; // not reached
}
CCEmap_cand = (*CCEmap)&CCEmap_mask;
@@ -2586,7 +2682,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint
*/
crc = (crc16(dci_decoded_output,sizeof_bits)>>16) ^ extract_crc(dci_decoded_output,sizeof_bits);
#ifdef DEBUG_DCI_DECODING
msg("crc =>%x\n",crc);
printf("crc =>%x\n",crc);
#endif
if (((L>1) && ((crc == si_rnti)||
@@ -2603,7 +2699,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint
dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[2];
dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[3];
#ifdef DEBUG_DCI_DECODING
msg("DCI => %x,%x,%x,%x\n",dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3]);
printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3]);
#endif
} else {
dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[0];
@@ -2615,7 +2711,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **lte_ue_pdcch_vars,int do_common,uint
dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[6];
dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[7];
#ifdef DEBUG_DCI_DECODING
msg("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
dci_decoded_output[0],dci_decoded_output[1],dci_decoded_output[2],dci_decoded_output[3],
dci_decoded_output[4],dci_decoded_output[5],dci_decoded_output[6],dci_decoded_output[7]);
#endif
@@ -2706,6 +2802,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
uint8_t tmode = phy_vars_ue->transmission_mode[eNB_id];
uint8_t frame_type = frame_parms->frame_type;
uint8_t format1A_size_bits=0,format1A_size_bytes=0;
uint8_t format1C_size_bits=0,format1C_size_bytes=0;
uint8_t format0_size_bits=0,format0_size_bytes=0;
uint8_t format1_size_bits=0,format1_size_bytes=0;
uint8_t format2_size_bits=0,format2_size_bytes=0;
@@ -2716,6 +2813,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
if (frame_type == TDD) {
format1A_size_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
format1A_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
format1C_size_bits = sizeof_DCI1C_1_5MHz_t;
format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
format0_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t;
format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
format1_size_bits = sizeof_DCI1_1_5MHz_TDD_t;
@@ -2735,6 +2834,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
} else {
format1A_size_bits = sizeof_DCI1A_1_5MHz_FDD_t;
format1A_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
format1C_size_bits = sizeof_DCI1C_1_5MHz_t;
format1C_size_bytes = sizeof(DCI1C_1_5MHz_t);
format0_size_bits = sizeof_DCI0_1_5MHz_FDD_t;
format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
format1_size_bits = sizeof_DCI1_1_5MHz_FDD_t;
@@ -2760,6 +2861,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
if (frame_type == TDD) {
format1A_size_bits = sizeof_DCI1A_5MHz_TDD_1_6_t;
format1A_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
format1C_size_bits = sizeof_DCI1C_5MHz_t;
format1C_size_bytes = sizeof(DCI1C_5MHz_t);
format0_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t;
format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
format1_size_bits = sizeof_DCI1_5MHz_TDD_t;
@@ -2779,6 +2882,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
} else {
format1A_size_bits = sizeof_DCI1A_5MHz_FDD_t;
format1A_size_bytes = sizeof(DCI1A_5MHz_FDD_t);
format1C_size_bits = sizeof_DCI1C_5MHz_t;
format1C_size_bytes = sizeof(DCI1C_5MHz_t);
format0_size_bits = sizeof_DCI0_5MHz_FDD_t;
format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
format1_size_bits = sizeof_DCI1_5MHz_FDD_t;
@@ -2803,6 +2908,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
if (frame_type == TDD) {
format1A_size_bits = sizeof_DCI1A_10MHz_TDD_1_6_t;
format1A_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
format1C_size_bits = sizeof_DCI1C_10MHz_t;
format1C_size_bytes = sizeof(DCI1C_10MHz_t);
format0_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t;
format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
format1_size_bits = sizeof_DCI1_10MHz_TDD_t;
@@ -2822,6 +2929,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
} else {
format1A_size_bits = sizeof_DCI1A_10MHz_FDD_t;
format1A_size_bytes = sizeof(DCI1A_10MHz_FDD_t);
format1C_size_bits = sizeof_DCI1C_10MHz_t;
format1C_size_bytes = sizeof(DCI1C_10MHz_t);
format0_size_bits = sizeof_DCI0_10MHz_FDD_t;
format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
format1_size_bits = sizeof_DCI1_10MHz_FDD_t;
@@ -2846,6 +2955,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
if (frame_type == TDD) {
format1A_size_bits = sizeof_DCI1A_20MHz_TDD_1_6_t;
format1A_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
format1C_size_bits = sizeof_DCI1C_20MHz_t;
format1C_size_bytes = sizeof(DCI1C_20MHz_t);
format0_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t;
format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
format1_size_bits = sizeof_DCI1_20MHz_TDD_t;
@@ -2865,6 +2976,8 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
} else {
format1A_size_bits = sizeof_DCI1A_20MHz_FDD_t;
format1A_size_bytes = sizeof(DCI1A_20MHz_FDD_t);
format1C_size_bits = sizeof_DCI1C_20MHz_t;
format1C_size_bytes = sizeof(DCI1C_20MHz_t);
format0_size_bits = sizeof_DCI0_20MHz_FDD_t;
format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
format1_size_bits = sizeof_DCI1_20MHz_FDD_t;
@@ -2894,7 +3007,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
if (phy_vars_ue->prach_resources[eNB_id])
ra_rnti = phy_vars_ue->prach_resources[eNB_id]->ra_RNTI;
// First check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI format 0/1A),
// First check common search spaces at aggregation 4 (SI_RNTI and RA_RNTI format 0/1A),
// and UE_SPEC format0 (PUSCH) too while we're at it
dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
dci_alloc,
@@ -2920,8 +3033,32 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
((format0_found==1)&&(format_c_found==1)))
return(dci_cnt);
//#ifdef ALL_AGGREGATION
// Disabled for performance
// Now check common search spaces at aggregation 4 (SI_RNTI and RA_RNTI and C-RNTI format 1C),
// and UE_SPEC format0 (PUSCH) too while we're at it
dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
2,
format1C,
format1C,
format1C,
format1C_size_bits,
format1C_size_bytes,
&dci_cnt,
&format0_found,
&format_c_found,
&CCEmap0,
&CCEmap1,
&CCEmap2);
if ((CCEmap0==0xffff) ||
((format0_found==1)&&(format_c_found==1)))
return(dci_cnt);
// Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI format 1A),
// and UE_SPEC format0 (PUSCH) too while we're at it
// printf("[DCI search] doing common search/format0 aggregation 3\n");
@@ -2952,6 +3089,27 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
((format0_found==1)&&(format_c_found==1)))
return(dci_cnt);
// Now check common search spaces at aggregation 8 (SI_RNTI and RA_RNTI and C-RNTI format 1C),
// and UE_SPEC format0 (PUSCH) too while we're at it
dci_decoding_procedure0(lte_ue_pdcch_vars,1,subframe,
dci_alloc,
eNB_id,
frame_parms,
mi,
SI_RNTI,
ra_rnti,
3,
format1C,
format1C,
format1C,
format1C_size_bits,
format1C_size_bytes,
&dci_cnt,
&format0_found,
&format_c_found,
&CCEmap0,
&CCEmap1,
&CCEmap2);
//#endif
}
+66 -7
View File
@@ -829,14 +829,73 @@ struct DCI1B_5MHz_4A_TDD {
typedef struct DCI1B_5MHz_4A_TDD DCI1B_5MHz_4A_TDD_t;
#define sizeof_DCI1B_5MHz_4A_TDD_t 31
/// DCI Format Type 1C (5 MHz, 12 bits)
typedef struct __attribute__ ((__packed__))
/// DCI Format Type 1C (1.4 MHz, 8 bits)
struct DCI1C_1_5MHz
{
uint32_t rballoc:7;
uint32_t tbs_index:5;
}
DCI1C_5MHz_t;
#define sizeof_DCI1C_5MHz_t 12
/// padding to 32bits
uint32_t padding32:24;
uint32_t mcs:5;
uint32_t rballoc:3; // N_RB_step = 2, Ngap=Ngap1=3, NDLVRBGap = 6, ceil(log2((3*4)/2)) = 3
} __attribute__ ((__packed__));
typedef struct DCI1C_1_5MHz DCI1C_1_5MHz_t;
#define sizeof_DCI1C_1_5MHz_t 8
/*********************************************************
**********************************************************/
/// DCI Format Type 1C (5 MHz, 12 bits)
struct DCI1C_5MHz
{
/// padding to 32bits
uint32_t padding32:20;
uint32_t mcs:5;
uint32_t rballoc:7; // N_RB_step = 2, Ngap1=Ngap2=12, NDLVRBGap = 24, ceil(log2((12*13)/2)) = 7
} __attribute__ ((__packed__));
typedef struct DCI1C_5MHz DCI1C_5MHz_t;
#define sizeof_DCI1C_5MHz_t 12
/// DCI Format Type 1C (10 MHz, 13 bits)
struct DCI1C_10MHz
{
/// padding to 32bits
uint32_t padding32:19;
uint32_t mcs:5;
uint32_t rballoc:7; // N_RB_step = 4, Ngap1=27, NDLVRBGap = 46, ceil(log2(((11*12)/2)) = 7
uint32_t Ngap:1;
} __attribute__ ((__packed__));
typedef struct DCI1C_10MHz DCI1C_10MHz_t;
#define sizeof_DCI1C_10MHz_t 13
/// DCI Format Type 1C (15 MHz, 14 bits)
struct DCI1C_15MHz
{
/// padding to 32bits
uint32_t padding32:18;
uint32_t mcs:5;
uint32_t rballoc:8; // N_RB_step = 4, Ngap1=64, ceil(log2((16*17)/2)) = 8
uint32_t Ngap:1;
} __attribute__ ((__packed__));
typedef struct DCI1C_15MHz DCI1C_15MHz_t;
#define sizeof_DCI1C_15MHz_t X
/// DCI Format Type 1C (20 MHz, 15 bits)
struct DCI1C_20MHz
{
/// padding to 32bits
uint32_t padding32:17;
uint32_t mcs:5;
uint32_t rballoc:9; // N_RB_step = 4, Ngap1=48, ceil(log2((24*25)/2)) = 9
uint32_t Ngap:1;
} __attribute__ ((__packed__));
typedef struct DCI1C_20MHz DCI1C_20MHz_t;
#define sizeof_DCI1C_20MHz_t 15
/*********************************************************
**********************************************************/
/// DCI Format Type 1D (5 MHz, FDD, 2 Antenna Ports, 27 bits)
struct DCI1D_5MHz_2A_FDD {
File diff suppressed because it is too large Load Diff
+27 -3
View File
@@ -114,6 +114,10 @@ typedef struct {
uint8_t *c[MAX_NUM_DLSCH_SEGMENTS];
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS];
/// Frame where current HARQ round was sent
uint32_t frame;
/// Subframe where current HARQ round was sent
uint32_t subframe;
/// Index of current HARQ round for this DLSCH
uint8_t round;
/// MCS format for this DLSCH
@@ -124,6 +128,8 @@ typedef struct {
MIMO_mode_t mimo_mode;
/// Current RB allocation
uint32_t rb_alloc[4];
/// distributed/localized flag
vrb_t vrb_type;
/// Current subband PMI allocation
uint16_t pmi_alloc;
/// Current subband RI allocation
@@ -139,7 +145,7 @@ typedef struct {
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t e[MAX_NUM_CHANNEL_BITS];
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
uint8_t d[MAX_NUM_DLSCH_SEGMENTS][(96+3+(3*6144))];
uint8_t *d[MAX_NUM_DLSCH_SEGMENTS];//[(96+3+(3*6144))];
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
uint8_t w[MAX_NUM_DLSCH_SEGMENTS][3*6144];
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
@@ -515,6 +521,8 @@ typedef struct {
uint8_t round;
/// MCS format for this DLSCH
uint8_t mcs;
/// Qm (modulation order) for this DLSCH
uint8_t Qm;
/// Redundancy-version of the current sub-frame
uint8_t rvidx;
/// MIMO mode for this DLSCH
@@ -547,8 +555,12 @@ typedef struct {
uint16_t nb_rb;
/// Current subband PMI allocation
uint16_t pmi_alloc;
/// Current RB allocation
uint32_t rb_alloc[4];
/// Current RB allocation (even slots)
uint32_t rb_alloc_even[4];
/// Current RB allocation (odd slots)
uint32_t rb_alloc_odd[4];
/// distributed/localized flag
vrb_t vrb_type;
/// downlink power offset field
uint8_t dl_power_off;
} LTE_DL_UE_HARQ_t;
@@ -563,6 +575,16 @@ typedef struct {
typedef struct {
/// UL RSSI per receive antenna
int32_t UL_rssi[NB_ANTENNAS_RX];
/// PUCCH1a/b power (digital linear)
int32_t Po_PUCCH;
/// PUCCH1a/b power (dBm)
int32_t Po_PUCCH_dBm;
/// PUCCH1 power (digital linear), conditioned on below threshold
int32_t Po_PUCCH1_below;
/// PUCCH1 power (digital linear), conditioned on above threshold
int32_t Po_PUCCH1_above;
/// Indicator that Po_PUCCH has been updated by PHY
int32_t Po_PUCCH_update;
/// DL Wideband CQI index (2 TBs)
uint8_t DL_cqi[2];
/// DL Subband CQI index (from HLC feedback)
@@ -673,6 +695,8 @@ typedef struct {
uint8_t Kmimo;
/// Maximum number of Turbo iterations
uint8_t max_turbo_iterations;
/// accumulated tx power adjustment for PUCCH
int8_t g_pucch;
} LTE_UE_DLSCH_t;
typedef enum {format0,
+17 -4
View File
@@ -100,6 +100,10 @@ void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
dlsch->harq_processes[i]->c[r] = NULL;
}
if (dlsch->harq_processes[i]->d[r]) {
free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
dlsch->harq_processes[i]->d[r] = NULL;
}
}
free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t));
@@ -168,14 +172,20 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
// account for filler in first segment and CRCs for multiple segment case
dlsch->harq_processes[i]->c[r] = (unsigned char*)malloc16(((r==0)?8:0) + 3+ 768);
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768);
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16((96+12+3+(3*6144)));
if (dlsch->harq_processes[i]->c[r]) {
bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768);
} else {
msg("Can't get c\n");
exit_flag=2;
}
if (dlsch->harq_processes[i]->d[r]) {
bzero(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144)));
} else {
msg("Can't get d\n");
exit_flag=2;
}
}
}
} else {
@@ -190,8 +200,10 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne
if (abstraction_flag==0) {
for (j=0; j<96; j++)
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
// printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]);
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
}
}
}
@@ -230,7 +242,8 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch, uint8_t abstraction_flag)
if (abstraction_flag==0) {
for (j=0; j<96; j++)
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
if (dlsch->harq_processes[i]->d[r])
dlsch->harq_processes[i]->d[r][j] = LTE_NULL;
}
}
}
+48 -25
View File
@@ -45,7 +45,7 @@
#include "SCHED/extern.h"
#include "SIMULATION/TOOLS/defs.h"
//#define DEBUG_DLSCH_DECODING
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
{
@@ -244,8 +244,6 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
*/
A = harq_process->TBS; //2072 for QPSK 1/3
// mod_order = get_Qm(harq_process->mcs);
ret = dlsch->max_turbo_iterations;
@@ -278,8 +276,33 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
err_flag = 0;
r_offset = 0;
unsigned char bw_scaling =1;
switch (frame_parms->N_RB_DL) {
case 6:
bw_scaling =16;
break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
if (harq_process->C >= MAX_NUM_DLSCH_SEGMENTS/bw_scaling) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling);
return((1+dlsch->max_turbo_iterations));
}
for (r=0; r<harq_process->C; r++) {
// Get Turbo interleaver parameters
if (r<harq_process->Cminus)
Kr = harq_process->Kminus;
@@ -302,7 +325,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
}
#ifdef DEBUG_DLSCH_DECODING
msg("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? harq_process->F : 0);
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? harq_process->F : 0);
#endif
start_meas(dlsch_rate_unmatching_stats);
@@ -316,7 +339,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
harq_pid,r, G,
Kr*3,
harq_process->TBS,
get_Qm(harq_process->mcs),
harq_process->Qm,
harq_process->nb_rb,
harq_process->Nl,
harq_process->rvidx,
@@ -335,12 +358,12 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
dlsch->Kmimo,
harq_process->rvidx,
(harq_process->round==0)?1:0,
get_Qm(harq_process->mcs),
harq_process->Qm,
harq_process->Nl,
r,
&E)==-1) {
stop_meas(dlsch_rate_unmatching_stats);
msg("dlsch_decoding.c: Problem in rate_matching\n");
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
return(dlsch->max_turbo_iterations);
} else
stop_meas(dlsch_rate_unmatching_stats);
@@ -348,7 +371,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
r_offset += E;
/*
msg("Subblock deinterleaving, d %p w %p\n",
printf("Subblock deinterleaving, d %p w %p\n",
harq_process->d[r],
harq_process->w);
*/
@@ -366,29 +389,29 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
}
msg("decoder input(segment %d) :",r);
printf("decoder input(segment %d) :",r);
int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
msg("%d : %d\n",i,harq_process->d[r][96+i]);
msg("\n");*/
printf("%d : %d\n",i,harq_process->d[r][96+i]);
printf("\n");*/
#endif
// msg("Clearing c, %p\n",harq_process->c[r]);
// printf("Clearing c, %p\n",harq_process->c[r]);
memset(harq_process->c[r],0,Kr_bytes);
// msg("done\n");
// printf("done\n");
if (harq_process->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
/*
msg("decoder input(segment %d)\n",r);
printf("decoder input(segment %d)\n",r);
for (i=0;i<(3*8*Kr_bytes)+12;i++)
if ((harq_process->d[r][96+i]>7) ||
(harq_process->d[r][96+i] < -8))
msg("%d : %d\n",i,harq_process->d[r][96+i]);
msg("\n");
printf("%d : %d\n",i,harq_process->d[r][96+i]);
printf("\n");
*/
if (err_flag == 0) {
@@ -423,7 +446,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
//msg("CRC failed, segment %d\n",r);
//printf("CRC failed, segment %d\n",r);
err_flag = 1;
}
@@ -456,9 +479,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
offset = 0;
/*
msg("harq_pid %d\n",harq_pid);
msg("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
msg("C %d\n",harq_process->C);
printf("harq_pid %d\n",harq_pid);
printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
printf("C %d\n",harq_process->C);
*/
for (r=0; r<harq_process->C; r++) {
if (r<harq_process->Cminus)
@@ -474,9 +497,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
&harq_process->c[0][(harq_process->F>>3)],
Kr_bytes - (harq_process->F>>3)- ((harq_process->C>1)?3:0));
offset = Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0);
// msg("copied %d bytes to b sequence (harq_pid %d)\n",
// printf("copied %d bytes to b sequence (harq_pid %d)\n",
// Kr_bytes - (harq_process->F>>3),harq_pid);
// msg("b[0] = %x,c[%d] = %x\n",
// printf("b[0] = %x,c[%d] = %x\n",
// harq_process->b[0],
// harq_process->F>>3,
// harq_process->c[0][(harq_process->F>>3)]);
@@ -666,7 +689,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
case 0: // SI
dlsch_ue = phy_vars_ue->dlsch_ue_SI[eNB_id];
dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_eNB_SI;
// msg("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3);
// printf("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3);
memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
#ifdef DEBUG_DLSCH_DECODING
LOG_D(PHY,"SI Decoded\n");
@@ -767,9 +790,9 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
#ifdef DEBUG_DLSCH_DECODING
for (i=0; i<dlsch_ue->harq_processes[0]->TBS>>3; i++)
msg("%x.",dlsch_eNB->harq_processes[0]->b[i]);
printf("%x.",dlsch_eNB->harq_processes[0]->b[i]);
msg("\n");
printf("\n");
#endif
/*
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+14 -15
View File
@@ -302,10 +302,10 @@ break;
switch (mod_order0) {
case 2: //QPSK
//printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
// printf("%d(%d) : %d,%d => ",tti_offset,*jj,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
@@ -315,8 +315,8 @@ break;
*jj = *jj + 1;
//printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
// printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
case 4: //16QAM
@@ -1089,7 +1089,7 @@ int allocate_REs_in_RB_MCH(mod_sym_t **txdataF,
uint8_t first_re,last_re;
int inc;
#ifdef DEBUG_DLSCH_MODULATION
printf("allocate_re_MCH (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj]);
printf("allocate_re_MCH (mod %d): symbol_offset %d re_offset %d (%d), jj %d -> %d,%d, gain_lin_QPSK %d,txdataF %p\n",mod_order,symbol_offset,re_offset,skip_dc,*jj, x0[*jj], x0[1+*jj],gain_lin_QPSK,&txdataF[0][symbol_offset]);
#endif
last_re=12;
@@ -1117,9 +1117,9 @@ int allocate_REs_in_RB_MCH(mod_sym_t **txdataF,
switch (mod_order) {
case 2: //QPSK
// printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
// printf("%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++)
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
*jj = *jj + 1;
@@ -1128,8 +1128,8 @@ int allocate_REs_in_RB_MCH(mod_sym_t **txdataF,
*jj = *jj + 1;
// printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
// printf("%d,%d\n",((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
break;
case 4: //16QAM
@@ -1623,7 +1623,6 @@ int mch_modulation(mod_sym_t **txdataF,
LTE_DL_FRAME_PARMS *frame_parms,
LTE_eNB_DLSCH_t *dlsch)
{
uint8_t nsymb,nsymb_pmch;
uint32_t i,jj,re_allocated,symbol_offset;
uint16_t l,rb,re_offset;
@@ -1651,7 +1650,7 @@ int mch_modulation(mod_sym_t **txdataF,
for (l=2; l<nsymb_pmch; l++) {
#ifdef DEBUG_DLSCH_MODULATION
msg("Generating MCH (mod %d) in %d\n",mod_order, l);
printf("Generating MCH (mod %d) in subframe %d for symbol %d\n",mod_order, subframe_offset,l);
#endif
re_offset = frame_parms->first_carrier_offset;
@@ -1677,7 +1676,7 @@ int mch_modulation(mod_sym_t **txdataF,
else
qam_table_s = NULL;
// printf("Allocated rb %d, subframe_offset %d\n",rb,subframe_offset);
// printf("Allocated rb %d, subframe_offset %d,amp %d\n",rb,subframe_offset,amp);
allocate_REs_in_RB_MCH(txdataF,
&jj,
re_offset,
@@ -59,3 +59,5 @@ unsigned int TBStable[TBStable_rowCnt][110] = {{16,32,56,88,120,152,176,208,224,
{616,1256,1864,2536,3112,3752,4392,5160,5736,6200,6968,7480,8248,8760,9528,10296,10680,11448,12216,12576,13536,14112,14688,15264,15840,16416,16992,17568,18336,19080,19848,20616,20616,21384,22152,22920,23688,24496,24496,25456,26416,26416,27376,28336,28336,29296,29296,30576,31704,31704,32856,32856,34008,34008,35160,35160,36696,36696,37888,37888,39232,39232,40576,40576,40576,42368,42368,43816,43816,43816,45352,45352,46888,46888,46888,48936,48936,48936,51024,51024,51024,52752,52752,52752,55056,55056,55056,55056,57336,57336,57336,59256,59256,59256,61664,61664,61664,61664,63776,63776,63776,63776,66592,66592,66592,66592,68808,68808,68808,71112},
{712,1480,2216,2984,3752,4392,5160,5992,6712,7480,8248,8760,9528,10296,11064,11832,12576,13536,14112,14688,15264,16416,16992,17568,18336,19080,19848,20616,21384,22152,22920,23688,24496,25456,25456,26416,27376,28336,29296,29296,30576,30576,31704,32856,32856,34008,35160,35160,36696,36696,37888,37888,39232,40576,40576,40576,42368,42368,43816,43816,45352,45352,46888,46888,48936,48936,48936,51024,51024,52752,52752,52752,55056,55056,55056,55056,57336,57336,57336,59256,59256,59256,61664,61664,61664,63776,63776,63776,66592,66592,66592,68808,68808,68808,71112,71112,71112,73712,73712,75376,75376,75376,75376,75376,75376,75376,75376,75376,75376,75376}
};
unsigned int TBStable1C[32] = {40, 56, 72, 120, 136, 144, 176, 208, 224, 256, 280, 296, 328, 336, 392, 488, 552, 600, 632, 696, 776, 840, 904, 1000, 1064, 1128, 1224, 1288, 1384, 1480, 1608, 1736};
+1 -1
View File
@@ -26,7 +26,7 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
extern unsigned int dlsch_tbs25[27][25],TBStable[27][110];
extern unsigned int dlsch_tbs25[27][25],TBStable[27][110],TBStable1C[32];
extern unsigned short lte_cqi_eff1024[16];
extern char lte_cqi_snr_dB[15];
extern short conjugate[8],conjugate2[8];
+111 -35
View File
@@ -48,14 +48,18 @@
#include "gain_control.h"
#endif
#if defined(OAI_USRP) || defined(EXMIMO)
#include "common_lib.h"
extern openair0_config_t openair0_cfg[];
#endif
#define DEBUG_INITIAL_SYNCH
int pbch_detection(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
int pbch_detection(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
{
uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->lte_frame_parms;
char phich_resource[6];
uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->lte_frame_parms;
char phich_resource[6];
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",phy_vars_ue->Mod_id,
@@ -65,25 +69,46 @@ int pbch_detection(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
slot_fep(phy_vars_ue,
l,
1,
phy_vars_ue->rx_offset,
0);
}
l,
0,
phy_vars_ue->rx_offset,
0,
1);
}
for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
slot_fep(phy_vars_ue,
l,
1,
phy_vars_ue->rx_offset,
0,
1);
}
slot_fep(phy_vars_ue,
0,
2,
phy_vars_ue->rx_offset,
0);
0,
2,
phy_vars_ue->rx_offset,
0,
1);
lte_ue_measurements(phy_vars_ue,
phy_vars_ue->rx_offset,
0,
0);
phy_vars_ue->rx_offset,
0,
0);
if (phy_vars_ue->lte_frame_parms.frame_type == TDD) {
ue_rrc_measurements(phy_vars_ue,
1,
0);
}
else {
ue_rrc_measurements(phy_vars_ue,
0,
0);
}
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE %d][initial sync] RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
LOG_I(PHY,"[UE %d] RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
phy_vars_ue->Mod_id,
phy_vars_ue->PHY_measurements.rx_rssi_dBm[0] - ((phy_vars_ue->lte_frame_parms.nb_antennas_rx==2) ? 3 : 0),
phy_vars_ue->PHY_measurements.rx_power_dB[0][0],
@@ -94,7 +119,7 @@ int pbch_detection(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
phy_vars_ue->PHY_measurements.rx_power_avg[0],
phy_vars_ue->rx_total_gain_dB);
LOG_I(PHY,"[UE %d][initial sync] N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
LOG_I(PHY,"[UE %d] N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
phy_vars_ue->Mod_id,
phy_vars_ue->PHY_measurements.n0_power_tot_dBm,
phy_vars_ue->PHY_measurements.n0_power_dB[0],
@@ -242,6 +267,10 @@ int pbch_detection(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
}
char phich_string[13][4] = {"","1/6","","1/2","","","one","","","","","","two"};
char duplex_string[2][4] = {"FDD","TDD"};
char prefix_string[2][9] = {"NORMAL","EXTENDED"};
int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
{
@@ -251,20 +280,33 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
uint8_t flip_fdd_ncp,flip_fdd_ecp,flip_tdd_ncp,flip_tdd_ecp;
// uint16_t Nid_cell_fdd_ncp=0,Nid_cell_fdd_ecp=0,Nid_cell_tdd_ncp=0,Nid_cell_tdd_ecp=0;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
// uint8_t i;
int i;
int ret=-1;
int aarx,rx_power=0;
/*#ifdef OAI_USRP
__m128i *rxdata128;
#endif*/
// LOG_I(PHY,"**************************************************************\n");
// First try FDD normal prefix
frame_parms->Ncp=NORMAL;
frame_parms->frame_type=FDD;
init_frame_parms(frame_parms,1);
// write_output("rxdata0.m","rxd0",phy_vars_ue->lte_ue_common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
/*#ifdef OAI_USRP
for (aarx = 0; aarx<frame_parms->nb_antennas_rx;aarx++) {
rxdata128 = (__m128i*)phy_vars_ue->lte_ue_common_vars.rxdata[aarx];
for (i=0; i<(frame_parms->samples_per_tti*10)>>2; i++) {
rxdata128[i] = _mm_srai_epi16(rxdata128[i],4);
}
}
#endif*/
sync_pos = lte_sync_time(phy_vars_ue->lte_ue_common_vars.rxdata,
frame_parms,
(int *)&phy_vars_ue->lte_ue_common_vars.eNb_id);
// write_output("rxdata1.m","rxd1",phy_vars_ue->lte_ue_common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
if (sync_pos >= frame_parms->nb_prefix_samples)
sync_pos2 = sync_pos - frame_parms->nb_prefix_samples;
else
@@ -322,6 +364,7 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
init_frame_parms(&phy_vars_ue->lte_frame_parms,1);
lte_gold(frame_parms,phy_vars_ue->lte_gold_table[0],frame_parms->Nid_cell);
ret = pbch_detection(phy_vars_ue,mode);
// write_output("rxdata2.m","rxd2",phy_vars_ue->lte_ue_common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"FDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
@@ -368,7 +411,7 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
init_frame_parms(&phy_vars_ue->lte_frame_parms,1);
lte_gold(frame_parms,phy_vars_ue->lte_gold_table[0],frame_parms->Nid_cell);
ret = pbch_detection(phy_vars_ue,mode);
// write_output("rxdata3.m","rxd3",phy_vars_ue->lte_ue_common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"FDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
frame_parms->Nid_cell,metric_fdd_ecp,phase_fdd_ecp,flip_fdd_ecp,ret);
@@ -415,7 +458,7 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
lte_gold(frame_parms,phy_vars_ue->lte_gold_table[0],frame_parms->Nid_cell);
ret = pbch_detection(phy_vars_ue,mode);
// write_output("rxdata4.m","rxd4",phy_vars_ue->lte_ue_common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"TDD Normal prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
@@ -462,6 +505,7 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
lte_gold(frame_parms,phy_vars_ue->lte_gold_table[0],frame_parms->Nid_cell);
ret = pbch_detection(phy_vars_ue,mode);
// write_output("rxdata5.m","rxd5",phy_vars_ue->lte_ue_common_vars.rxdata[0],10*frame_parms->samples_per_tti,1,1);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"TDD Extended prefix: CellId %d metric %d, phase %d, flip %d, pbch %d\n",
frame_parms->Nid_cell,metric_tdd_ecp,phase_tdd_ecp,flip_tdd_ecp,ret);
@@ -480,26 +524,56 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
if (ret==0) { // PBCH found so indicate sync to higher layers and configure frame parameters
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[PHY][UE%d] In synch, rx_offset %d samples\n",phy_vars_ue->Mod_id, phy_vars_ue->rx_offset);
LOG_I(PHY,"[UE%d] In synch, rx_offset %d samples\n",phy_vars_ue->Mod_id, phy_vars_ue->rx_offset);
#endif
if (phy_vars_ue->UE_scan_carrier == 0) {
#ifdef OPENAIR2
LOG_I(PHY,"[PHY][UE%d] Sending synch status to higher layers\n",phy_vars_ue->Mod_id);
//mac_resynch();
mac_xface->dl_phy_sync_success(phy_vars_ue->Mod_id,phy_vars_ue->frame_rx,0,1);//phy_vars_ue->lte_ue_common_vars.eNb_id);
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",phy_vars_ue->Mod_id);
//mac_resynch();
mac_xface->dl_phy_sync_success(phy_vars_ue->Mod_id,phy_vars_ue->frame_rx,0,1);//phy_vars_ue->lte_ue_common_vars.eNb_id);
#endif //OPENAIR2
generate_pcfich_reg_mapping(frame_parms);
generate_phich_reg_mapping(frame_parms);
// init_prach625(frame_parms);
generate_pcfich_reg_mapping(frame_parms);
generate_phich_reg_mapping(frame_parms);
// init_prach625(frame_parms);
#ifndef OPENAIR2
phy_vars_ue->UE_mode[0] = PUSCH;
phy_vars_ue->UE_mode[0] = PUSCH;
#else
phy_vars_ue->UE_mode[0] = PRACH;
phy_vars_ue->UE_mode[0] = PRACH;
#endif
//phy_vars_ue->lte_ue_pbch_vars[0]->pdu_errors=0;
phy_vars_ue->lte_ue_pbch_vars[0]->pdu_errors_conseq=0;
//phy_vars_ue->lte_ue_pbch_vars[0]->pdu_errors=0;
phy_vars_ue->lte_ue_pbch_vars[0]->pdu_errors_conseq=0;
//phy_vars_ue->lte_ue_pbch_vars[0]->pdu_errors_last=0;
}
LOG_I(PHY,"[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",phy_vars_ue->Mod_id,
phy_vars_ue->frame_rx,
10*log10(phy_vars_ue->PHY_measurements.rssi)-phy_vars_ue->rx_total_gain_dB,
10*log10(phy_vars_ue->PHY_measurements.rssi),
phy_vars_ue->rx_total_gain_dB,
phy_vars_ue->PHY_measurements.n0_power_tot_dBm,
10*log10(phy_vars_ue->PHY_measurements.rsrp[0])-phy_vars_ue->rx_total_gain_dB,
(10*log10(phy_vars_ue->PHY_measurements.rsrq[0])));
LOG_I(PHY,"[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
phy_vars_ue->Mod_id,
phy_vars_ue->frame_rx,
duplex_string[phy_vars_ue->lte_frame_parms.frame_type],
prefix_string[phy_vars_ue->lte_frame_parms.Ncp],
phy_vars_ue->lte_frame_parms.Nid_cell,
phy_vars_ue->lte_frame_parms.N_RB_DL,
phy_vars_ue->lte_frame_parms.phich_config_common.phich_duration,
phich_string[phy_vars_ue->lte_frame_parms.phich_config_common.phich_resource],
phy_vars_ue->lte_frame_parms.nb_antennas_tx_eNB);
#if defined(OAI_USRP) || defined(EXMIMO)
LOG_I(PHY,"[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
phy_vars_ue->Mod_id,
phy_vars_ue->frame_rx,
openair0_cfg[0].rx_freq[0]-phy_vars_ue->lte_ue_common_vars.freq_offset,
phy_vars_ue->lte_ue_common_vars.freq_offset);
#endif
} else {
#ifdef DEBUG_INITIAL_SYNC
LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",phy_vars_ue->Mod_id);
@@ -521,5 +595,7 @@ int initial_sync(PHY_VARS_UE *phy_vars_ue, runmode_t mode)
}
// exit_fun("debug exit");
return ret;
}
+53 -13
View File
@@ -531,7 +531,7 @@ uint16_t pbch_extract(int **rxdataF,
return(0);
}
__m128i avg128;
//__m128i avg128;
//compute average channel_level on each (TX,RX) antenna pair
int pbch_channel_level(int **dl_ch_estimates_ext,
@@ -541,7 +541,14 @@ int pbch_channel_level(int **dl_ch_estimates_ext,
int16_t rb, nb_rb=6;
uint8_t aatx,aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i avg128;
__m128i *dl_ch128;
#elif defined(__arm__)
int32x4_t avg128;
int16x8_t *dl_ch128;
#endif
int avg1=0,avg2=0;
uint32_t nsymb = (frame_parms->Ncp==0) ? 7:6;
@@ -550,15 +557,23 @@ int pbch_channel_level(int **dl_ch_estimates_ext,
for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antennas_tx_eNB;aatx++)
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_setzero_si128();
dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12];
#elif defined(__arm__)
avg128 = vdupq_n_s32(0);
dl_ch128=(int16x8_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12];
#endif
for (rb=0; rb<nb_rb; rb++) {
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[1],dl_ch128[1]));
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[2],dl_ch128[2]));
#elif defined(__arm__)
// to be filled in
#endif
dl_ch128+=3;
/*
if (rb==0) {
@@ -579,16 +594,19 @@ int pbch_channel_level(int **dl_ch_estimates_ext,
//msg("Channel level : %d, %d\n",avg1, avg2);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(avg2);
}
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
void pbch_channel_compensation(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **rxdataF_comp,
@@ -599,21 +617,28 @@ void pbch_channel_compensation(int **rxdataF_ext,
uint16_t rb,nb_rb=6;
uint8_t aatx,aarx,symbol_mod;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
#elif defined(__arm__)
#endif
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
for (aatx=0; aatx<4; aatx++) //frame_parms->nb_antennas_tx_eNB;aatx++)
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol_mod*6*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol_mod*6*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx<<1)+aarx][symbol_mod*6*12];
#elif defined(__arm__)
// to be filled in
#endif
for (rb=0; rb<nb_rb; rb++) {
//printf("rb %d\n",rb);
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpP0);
@@ -680,11 +705,15 @@ void pbch_channel_compensation(int **rxdataF_ext,
rxdataF128+=2;
rxdataF_comp128+=2;
}
#elif defined(__arm__)
// to be filled in
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void pbch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
@@ -694,24 +723,38 @@ void pbch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t aatx, symbol_mod;
int i, nb_rb=6;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1;
#elif defined(__arm__)
int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1;
#endif
symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
if (frame_parms->nb_antennas_rx>1) {
for (aatx=0; aatx<4; aatx++) { //frame_parms->nb_antennas_tx_eNB;aatx++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12];
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol_mod*6*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol_mod*6*12];
#endif
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
#elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
#endif
}
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
@@ -806,9 +849,6 @@ void pbch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
}
_mm_empty();
_m_empty();
}
void pbch_quantize(int8_t *pbch_llr8,
+3 -3
View File
@@ -78,9 +78,9 @@ void generate_pcfich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
first_reg = pcfich_reg[3];
}
#ifdef DEBUG_PCFICH
msg("[PHY] pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]);
#endif
//#ifdef DEBUG_PCFICH
printf("pcfich_reg : %d,%d,%d,%d\n",pcfich_reg[0],pcfich_reg[1],pcfich_reg[2],pcfich_reg[3]);
//#endif
}
void pcfich_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
+31 -19
View File
@@ -291,6 +291,7 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
// compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211
Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
Ngroup_PHICH++;
@@ -299,16 +300,25 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
Ngroup_PHICH<<=1;
}
#ifdef DEBUG_PHICH
LOG_D(PHY,"Ngroup_PHICH %d (phich_config_common.phich_resource %d,NidCell %d,Ncp %d, frame_type %d)\n",((frame_parms->Ncp == 0)?Ngroup_PHICH:(Ngroup_PHICH>>1)),
frame_parms->phich_config_common.phich_resource,
frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type);
#endif
//#ifdef DEBUG_PHICH
printf("Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n",
((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)),
frame_parms->phich_config_common.phich_resource,
frame_parms->phich_config_common.phich_duration==normal?"normal":"extended",
frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type,
pcfich_reg[frame_parms->pcfich_first_reg_idx],
n0,
n1,
((frame_parms->Nid_cell))%n0);
//#endif
// This is the algorithm from Section 6.9.3 in 36-211
for (mprime=0; mprime<((frame_parms->Ncp == 0)?Ngroup_PHICH:(Ngroup_PHICH>>1)); mprime++) {
// This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ...
if (frame_parms->Ncp==0) { // normal prefix
for (mprime=0;
mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1));
mprime++) {
if (frame_parms->phich_config_common.phich_duration==normal) { // normal PHICH duration
frame_parms->phich_reg[mprime][0] = (frame_parms->Nid_cell + mprime)%n0;
@@ -326,9 +336,10 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
frame_parms->phich_reg[mprime][1] = (frame_parms->Nid_cell + mprime + (n0/3))%n0;
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
frame_parms->phich_reg[mprime][1]++;
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3])
frame_parms->phich_reg[mprime][1]++;
@@ -337,9 +348,10 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
frame_parms->phich_reg[mprime][1]++;
frame_parms->phich_reg[mprime][2] = (frame_parms->Nid_cell + mprime + (2*n0/3))%n0;
if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[frame_parms->pcfich_first_reg_idx])
frame_parms->phich_reg[mprime][2]++;
@@ -351,11 +363,11 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3])
frame_parms->phich_reg[mprime][2]++;
#ifdef DEBUG_PHICH
LOG_D(PHY,"phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
#endif
} else { // extended prefix
//#ifdef DEBUG_PHICH
printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
//#endif
} else { // extended PHICH duration
frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0;
frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0;
@@ -364,10 +376,10 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms)
frame_parms->phich_reg[1+(mprime<<1)][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1;
frame_parms->phich_reg[1+(mprime<<1)][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2;
#ifdef DEBUG_PHICH
LOG_D(PHY,"phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
LOG_D(PHY,"phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]);
#endif
//#ifdef DEBUG_PHICH
printf("phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]);
printf("phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]);
//#endif
}
} // mprime loop
} // num_pdcch_symbols loop
+174 -23
View File
@@ -257,23 +257,31 @@ void fill_UE_dlsch_MCH(PHY_VARS_UE *phy_vars_ue,int mcs,int ndi,int rvidx,int eN
switch(frame_parms->N_RB_DL) {
case 6:
dlsch->harq_processes[0]->rb_alloc[0] = 0x3f;
dlsch->harq_processes[0]->rb_alloc_even[0] = 0x3f;
dlsch->harq_processes[0]->rb_alloc_odd[0] = 0x3f;
break;
case 25:
dlsch->harq_processes[0]->rb_alloc[0] = 0x1ffffff;
dlsch->harq_processes[0]->rb_alloc_even[0] = 0x1ffffff;
dlsch->harq_processes[0]->rb_alloc_odd[0] = 0x1ffffff;
break;
case 50:
dlsch->harq_processes[0]->rb_alloc[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[1] = 0x3ffff;
dlsch->harq_processes[0]->rb_alloc_even[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_odd[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_even[1] = 0x3ffff;
dlsch->harq_processes[0]->rb_alloc_odd[1] = 0x3ffff;
break;
case 100:
dlsch->harq_processes[0]->rb_alloc[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[1] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[2] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[3] = 0xf;
dlsch->harq_processes[0]->rb_alloc_even[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_odd[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_even[1] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_odd[1] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_even[2] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_odd[2] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc_even[3] = 0xf;
dlsch->harq_processes[0]->rb_alloc_odd[3] = 0xf;
break;
}
}
@@ -395,22 +403,33 @@ void mch_channel_level(int **dl_ch_estimates_ext,
{
int i,aarx,nre;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,avg128;
#elif defined(__arm__)
int32x4_t avg128;
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
//clear average level
avg128 = _mm_setzero_si128();
// 5 is always a symbol with no pilots for both normal and extended prefix
dl_ch128=(__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
#endif
if ((symbol == 2) || (symbol == 6) || (symbol == 10))
nre = (frame_parms->N_RB_DL*6);
else
nre = (frame_parms->N_RB_DL*12);
for (i=0; i<(nre>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
#elif defined(__arm__)
#endif
}
avg[aarx] = (((int*)&avg128)[0] +
@@ -421,9 +440,10 @@ void mch_channel_level(int **dl_ch_estimates_ext,
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void mch_channel_compensation(int **rxdataF_ext,
@@ -438,14 +458,18 @@ void mch_channel_compensation(int **rxdataF_ext,
{
int aarx,nre,i;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128;
__m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b;
#elif defined(__arm__)
#endif
if ((symbol == 2) || (symbol == 6) || (symbol == 10))
nre = frame_parms->N_RB_DL*6;
else
nre = frame_parms->N_RB_DL*12;
#if defined(__x86_64__) || defined(__i386__)
if (mod_order == 4) {
QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10)
QAM_amp128b = _mm_setzero_si128();
@@ -453,21 +477,27 @@ void mch_channel_compensation(int **rxdataF_ext,
QAM_amp128 = _mm_set1_epi16(QAM64_n1); //
QAM_amp128b = _mm_set1_epi16(QAM64_n2);
}
#elif defined(__arm__)
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128 = (__m128i *)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128b = (__m128i *)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
#endif
for (i=0; i<(nre>>2); i+=2) {
if (mod_order>2) {
// get channel amplitude if not QPSK
#if defined(__x86_64__) || defined(__i386__)
mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]);
mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift);
@@ -497,8 +527,13 @@ void mch_channel_compensation(int **rxdataF_ext,
dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b);
dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1);
#elif defined(__arm__)
#endif
}
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpD0);
@@ -547,12 +582,17 @@ void mch_channel_compensation(int **rxdataF_ext,
rxdataF128+=2;
rxdataF_comp128+=2;
#elif defined(__arm__)
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
@@ -564,10 +604,15 @@ void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
int i;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b;
#elif defined(__arm__)
int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b;
#endif
if (frame_parms->nb_antennas_rx>1) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
@@ -575,16 +620,32 @@ void mch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128_0 = (int16x8_t *)&dl_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128_1 = (int16x8_t *)&dl_ch_mag[1][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128_0b = (int16x8_t *)&dl_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
dl_ch_mag128_1b = (int16x8_t *)&dl_ch_magb[1][symbol*frame_parms->N_RB_DL*12];
#endif
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<frame_parms->N_RB_DL*3; i++) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1));
dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1));
dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1));
#elif defined(__arm__)
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
dl_ch_mag128_0[i] = vhaddq_s16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
dl_ch_mag128_0b[i] = vhaddq_s16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
@@ -625,8 +686,10 @@ int mch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
*llr32p = (short *)llr32;
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(0);
}
@@ -643,22 +706,38 @@ void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
int16_t **llr32p)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *ch_mag;
__m128i llr128[2],xmm0;
uint32_t *llr32;
#elif defined(__arm__)
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int16x8_t *ch_mag;
int16x8_t llr128[2],xmm0;
int16_t *llr16;
#endif
int i,len;
unsigned char len_mod4=0;
uint32_t *llr32;
#if defined(__x86_64__) || defined(__i386__)
if (symbol==2) {
llr32 = (uint32_t*)dlsch_llr;
} else {
llr32 = (uint32_t*)*llr32p;
}
#elif defined(__arm__)
if (symbol==2) {
llr16 = (int16_t*)dlsch_llr;
} else {
llr16 = (int16_t*)*llr32p;
}
#endif
#if defined(__x86_64__) || defined(__i386__)
ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
#elif defined(__arm__)
ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
#endif
if ((symbol==2) || (symbol==6) || (symbol==10)) {
len = frame_parms->N_RB_DL*6;
} else {
@@ -679,6 +758,7 @@ void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
for (i=0; i<len; i++) {
#if defined(__x86_64__) || defined(__i386__)
xmm0 = _mm_abs_epi16(rxF[i]);
xmm0 = _mm_subs_epi16(ch_mag[i],xmm0);
@@ -694,10 +774,38 @@ void mch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
llr32[6] = ((uint32_t *)&llr128[1])[2];
llr32[7] = ((uint32_t *)&llr128[1])[3];
llr32+=8;
#elif defined(__arm__)
xmm0 = vabsq_s16(rxF[i]);
xmm0 = vsubq_s16(ch_mag[i],xmm0);
// lambda_1=y_R, lambda_2=|y_R|-|h|^2, lamda_3=y_I, lambda_4=|y_I|-|h|^2
llr16[0] = vgetq_lane_s16(rxF[i],0);
llr16[1] = vgetq_lane_s16(xmm0,0);
llr16[2] = vgetq_lane_s16(rxF[i],1);
llr16[3] = vgetq_lane_s16(xmm0,1);
llr16[4] = vgetq_lane_s16(rxF[i],2);
llr16[5] = vgetq_lane_s16(xmm0,2);
llr16[6] = vgetq_lane_s16(rxF[i],2);
llr16[7] = vgetq_lane_s16(xmm0,3);
llr16[8] = vgetq_lane_s16(rxF[i],4);
llr16[9] = vgetq_lane_s16(xmm0,4);
llr16[10] = vgetq_lane_s16(rxF[i],5);
llr16[11] = vgetq_lane_s16(xmm0,5);
llr16[12] = vgetq_lane_s16(rxF[i],6);
llr16[13] = vgetq_lane_s16(xmm0,6);
llr16[14] = vgetq_lane_s16(rxF[i],7);
llr16[15] = vgetq_lane_s16(xmm0,7);
llr16+=16;
#endif
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
//----------------------------------------------------------------------------------------------
@@ -713,8 +821,13 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
short **llr_save)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i xmm1,xmm2,*ch_mag,*ch_magb;
__m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
#elif defined(__arm__)
int16x8_t xmm1,xmm2,*ch_mag,*ch_magb;
int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
#endif
int i,len,len2;
// int j=0;
@@ -727,9 +840,13 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
else
llr = *llr_save;
#if defined(__x86_64__) || defined(__i386__)
ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)];
#elif defined(__arm__)
ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)];
#endif
if ((symbol==2) || (symbol==6) || (symbol==10)) {
len = frame_parms->N_RB_DL*6;
} else {
@@ -746,11 +863,18 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
for (i=0; i<len2; i++) {
#if defined(__x86_64__) || defined(__i386__)
xmm1 = _mm_abs_epi16(rxF[i]);
xmm1 = _mm_subs_epi16(ch_mag[i],xmm1);
xmm2 = _mm_abs_epi16(xmm1);
xmm2 = _mm_subs_epi16(ch_magb[i],xmm2);
#elif defined(__arm__)
xmm1 = vabsq_s16(rxF[i]);
xmm1 = vsubq_s16(ch_mag[i],xmm1);
xmm2 = vabsq_s16(xmm1);
xmm2 = vsubq_s16(ch_magb[i],xmm2);
#endif
/*
printf("pmch i: %d => mag (%d,%d) (%d,%d)\n",i,((short *)&ch_mag[i])[0],((short *)&ch_magb[i])[0],
((short *)&rxF[i])[0],((short *)&rxF[i])[1]);
@@ -770,41 +894,68 @@ void mch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
*/
llr2[0] = ((short *)&rxF[i])[0];
llr2[1] = ((short *)&rxF[i])[1];
#if defined(__x86_64__) || defined(__i386__)
llr2[2] = _mm_extract_epi16(xmm1,0);
llr2[3] = _mm_extract_epi16(xmm1,1);//((short *)&xmm1)[j+1];
llr2[4] = _mm_extract_epi16(xmm2,0);//((short *)&xmm2)[j];
llr2[5] = _mm_extract_epi16(xmm2,1);//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2[2] = vgetq_lane_s16(xmm1,0);
llr2[3] = vgetq_lane_s16(xmm1,1);//((short *)&xmm1)[j+1];
llr2[4] = vgetq_lane_s16(xmm2,0);//((short *)&xmm2)[j];
llr2[5] = vgetq_lane_s16(xmm2,1);//((short *)&xmm2)[j+1];
#endif
llr2+=6;
llr2[0] = ((short *)&rxF[i])[2];
llr2[1] = ((short *)&rxF[i])[3];
#if defined(__x86_64__) || defined(__i386__)
llr2[2] = _mm_extract_epi16(xmm1,2);
llr2[3] = _mm_extract_epi16(xmm1,3);//((short *)&xmm1)[j+1];
llr2[4] = _mm_extract_epi16(xmm2,2);//((short *)&xmm2)[j];
llr2[5] = _mm_extract_epi16(xmm2,3);//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2[2] = vgetq_lane_s16(xmm1,2);
llr2[3] = vgetq_lane_s16(xmm1,3);//((short *)&xmm1)[j+1];
llr2[4] = vgetq_lane_s16(xmm2,2);//((short *)&xmm2)[j];
llr2[5] = vgetq_lane_s16(xmm2,3);//((short *)&xmm2)[j+1];
#endif
llr2+=6;
llr2[0] = ((short *)&rxF[i])[4];
llr2[1] = ((short *)&rxF[i])[5];
#if defined(__x86_64__) || defined(__i386__)
llr2[2] = _mm_extract_epi16(xmm1,4);
llr2[3] = _mm_extract_epi16(xmm1,5);//((short *)&xmm1)[j+1];
llr2[4] = _mm_extract_epi16(xmm2,4);//((short *)&xmm2)[j];
llr2[5] = _mm_extract_epi16(xmm2,5);//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2[2] = vgetq_lane_s16(xmm1,4);
llr2[3] = vgetq_lane_s16(xmm1,5);//((short *)&xmm1)[j+1];
llr2[4] = vgetq_lane_s16(xmm2,4);//((short *)&xmm2)[j];
llr2[5] = vgetq_lane_s16(xmm2,5);//((short *)&xmm2)[j+1];
#endif
llr2+=6;
llr2[0] = ((short *)&rxF[i])[6];
llr2[1] = ((short *)&rxF[i])[7];
#if defined(__x86_64__) || defined(__i386__)
llr2[2] = _mm_extract_epi16(xmm1,6);
llr2[3] = _mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1];
llr2[4] = _mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j];
llr2[5] = _mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1];
#elif defined(__arm__)
llr2[2] = vgetq_lane_s16(xmm1,6);
llr2[3] = vgetq_lane_s16(xmm1,7);//((short *)&xmm1)[j+1];
llr2[4] = vgetq_lane_s16(xmm2,6);//((short *)&xmm2)[j];
llr2[5] = vgetq_lane_s16(xmm2,7);//((short *)&xmm2)[j+1];
#endif
llr2+=6;
}
*llr_save = llr;
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
int avg_pmch[4];
+74 -16
View File
@@ -435,6 +435,51 @@ uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type)
}
}
uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf)
{
lte_frame_type_t frame_type = frame_parms->frame_type;
uint8_t tdd_config = frame_parms->tdd_config;
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t n_ra_prboffset = frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
uint8_t n_ra_prb;
uint8_t f_ra,t1_ra;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
uint8_t Nsp=2;
if (frame_type == TDD) { // TDD
if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
LOG_E(PHY, "Illegal prach_ConfigIndex %"PRIu8"", prach_ConfigIndex);
return(-1);
}
// adjust n_ra_prboffset for frequency multiplexing (p.36 36.211)
f_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[tdd_mapindex].f_ra;
if (prach_fmt < 4) {
if ((f_ra&1) == 0) {
n_ra_prb = n_ra_prboffset + 6*(f_ra>>1);
} else {
n_ra_prb = frame_parms->N_RB_UL - 6 - n_ra_prboffset + 6*(f_ra>>1);
}
} else {
if ((tdd_config >2) && (tdd_config<6))
Nsp = 2;
t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
if ((((Nf&1)*(2-Nsp)+t1_ra)&1) == 0) {
n_ra_prb = 6*f_ra;
} else {
n_ra_prb = frame_parms->N_RB_UL - 6*(f_ra+1);
}
}
}
else { //FDD
n_ra_prb = n_ra_prboffset;
}
return(n_ra_prb);
}
int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe)
{
@@ -554,12 +599,12 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
{
lte_frame_type_t frame_type = phy_vars_ue->lte_frame_parms.frame_type;
uint8_t tdd_config = phy_vars_ue->lte_frame_parms.tdd_config;
//uint8_t tdd_config = phy_vars_ue->lte_frame_parms.tdd_config;
uint16_t rootSequenceIndex = phy_vars_ue->lte_frame_parms.prach_config_common.rootSequenceIndex;
uint8_t prach_ConfigIndex = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t Ncs_config = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
uint8_t restricted_set = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag;
uint8_t n_ra_prboffset = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
//uint8_t n_ra_prboffset = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
uint8_t preamble_index = phy_vars_ue->prach_resources[eNB_id]->ra_PreambleIndex;
uint8_t tdd_mapindex = phy_vars_ue->prach_resources[eNB_id]->ra_TDD_map_index;
int16_t *prachF = phy_vars_ue->lte_ue_prach_vars[eNB_id]->prachF;
@@ -576,8 +621,8 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
uint16_t d_start,numshift;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
uint8_t Nsp=2;
uint8_t f_ra,t1_ra;
//uint8_t Nsp=2;
//uint8_t f_ra,t1_ra;
uint16_t N_ZC = (prach_fmt<4)?839:139;
uint8_t not_found;
int k;
@@ -592,7 +637,7 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
#ifdef BIT8_TX
prach_start = ((subframe*phy_vars_ue->lte_frame_parms.samples_per_tti)<<1)-phy_vars_ue->N_TA_offset;
#else
#ifdef EXMIMO
#if defined(EXMIMO) || defined(OAI_USRP)
prach_start = (phy_vars_ue->rx_offset+subframe*phy_vars_ue->lte_frame_parms.samples_per_tti-openair_daq_vars.timing_advance-phy_vars_ue->N_TA_offset);
if (prach_start<0)
@@ -625,9 +670,11 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
NCS = NCS_restricted[Ncs_config];
}
n_ra_prb = n_ra_prboffset;
n_ra_prb = get_prach_prb_offset(&(phy_vars_ue->lte_frame_parms), tdd_mapindex, Nf);
prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4;
/*
// this code is not part of get_prach_prb_offset
if (frame_type == TDD) { // TDD
if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
@@ -656,6 +703,7 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
}
}
}
*/
// This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
@@ -979,7 +1027,17 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
((int16_t*)phy_vars_ue->lte_ue_common_vars.txdata[0])[2*i] = prach[2*j]<<4;
((int16_t*)phy_vars_ue->lte_ue_common_vars.txdata[0])[2*i+1] = prach[2*j+1]<<4;
}
#if defined(EXMIMO)
// handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
for (k=prach_start - (phy_vars_ue->lte_frame_parms.samples_per_tti>>1) ; k<prach_start ; k++) {
if (k<0)
phy_vars_ue->lte_ue_common_vars.txdata[0][k+phy_vars_ue->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
else if (k>(phy_vars_ue->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
phy_vars_ue->lte_ue_common_vars.txdata[0][k-phy_vars_ue->lte_frame_parms.samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
else
phy_vars_ue->lte_ue_common_vars.txdata[0][k] &= 0xFFFEFFFE;
}
#endif
#else
for (i=0; i<prach_len; i++) {
@@ -998,10 +1056,7 @@ int32_t generate_prach( PHY_VARS_UE *phy_vars_ue, uint8_t eNB_id, uint8_t subfra
return signal_energy( (int*)prach, 256 );
}
__m128i mmtmpX0,mmtmpX1,mmtmpX2,mmtmpX3;
//__m128i mmtmpX0,mmtmpX1,mmtmpX2,mmtmpX3;
void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_energy_list, uint16_t *preamble_delay_list, uint16_t Nf, uint8_t tdd_mapindex)
{
@@ -1009,12 +1064,12 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
int i;
lte_frame_type_t frame_type = phy_vars_eNB->lte_frame_parms.frame_type;
uint8_t tdd_config = phy_vars_eNB->lte_frame_parms.tdd_config;
//uint8_t tdd_config = phy_vars_eNB->lte_frame_parms.tdd_config;
uint16_t rootSequenceIndex = phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex;
uint8_t prach_ConfigIndex = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t Ncs_config = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
uint8_t restricted_set = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag;
uint8_t n_ra_prboffset = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
//uint8_t n_ra_prboffset = phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
int16_t *prachF = phy_vars_eNB->lte_eNB_prach_vars.prachF;
int16_t **rxsigF = phy_vars_eNB->lte_eNB_prach_vars.rxsigF;
int16_t **prach_ifft = phy_vars_eNB->lte_eNB_prach_vars.prach_ifft;
@@ -1031,8 +1086,8 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
uint16_t numshift=0;
uint16_t *prach_root_sequence_map;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
uint8_t Nsp=2;
uint8_t f_ra,t1_ra;
//uint8_t Nsp=2;
//uint8_t f_ra,t1_ra;
uint16_t N_ZC = (prach_fmt <4)?839:139;
uint8_t not_found;
// LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
@@ -1076,9 +1131,11 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
start_meas(&phy_vars_eNB->rx_prach);
n_ra_prb = n_ra_prboffset;
n_ra_prb = get_prach_prb_offset(&(phy_vars_eNB->lte_frame_parms),tdd_mapindex,Nf);
prach_root_sequence_map = (prach_fmt < 4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4;
/*
// this code is now part of get_prach_prb_offset
if (frame_type == TDD) { // TDD
// adjust n_ra_prboffset for frequency multiplexing (p.36 36.211)
@@ -1105,6 +1162,7 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,uint8_t subframe,uint16_t *preamble_ene
}
}
*/
// printf("NCS %d\n",NCS);
// PDP is oversampled, e.g. 1024 sample instead of 839
+33 -9
View File
@@ -67,8 +67,15 @@ int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t
if ((mode == normal_txrx) || (mode == no_L2_connect)) {
len += sprintf(&buffer[len], "[UE_PROC] UE %d, RNTI %x\n",phy_vars_ue->Mod_id, phy_vars_ue->lte_ue_pdcch_vars[0]->crnti);
len += sprintf(&buffer[len],"[UE PROC] RSRP[0] %.2f dBm/RE, RSSI %.2f dBm, RSRQ[0] %.2f dB, N0 %d dBm/RE\n",
10*log10(phy_vars_ue->PHY_measurements.rsrp[0])-phy_vars_ue->rx_total_gain_dB,
10*log10(phy_vars_ue->PHY_measurements.rssi)-phy_vars_ue->rx_total_gain_dB,
10*log10(phy_vars_ue->PHY_measurements.rsrq[0]),
phy_vars_ue->PHY_measurements.n0_power_tot_dBm);
/*
len += sprintf(&buffer[len],
"[UE PROC] Frame count: %d\neNB0 RSSI %d dBm/RE (%d dB, %d dB)\neNB1 RSSI %d dBm/RE (%d dB, %d dB)\neNB2 RSSI %d dBm/RE (%d dB, %d dB)\nN0 %d dBm/RE, %f dBm/%dPRB (%d dB, %d dB)\n",
"[UE PROC] Frame count: %d\neNB0 RSSI %d dBm/RE (%d dB, %d dB)\neNB1 RSSI %d dBm/RE (%d dB, %d dB)neNB2 RSSI %d dBm/RE (%d dB, %d dB)\nN0 %d dBm/RE, %f dBm/%dPRB (%d dB, %d dB)\n",
phy_vars_ue->frame_rx,
phy_vars_ue->PHY_measurements.rx_rssi_dBm[0],
phy_vars_ue->PHY_measurements.rx_power_dB[0][0],
@@ -84,18 +91,32 @@ int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t
phy_vars_ue->lte_frame_parms.N_RB_DL,
phy_vars_ue->PHY_measurements.n0_power_dB[0],
phy_vars_ue->PHY_measurements.n0_power_dB[1]);
*/
#ifdef EXMIMO
len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB (LNA %d, vga %d dB)\n",phy_vars_ue->rx_total_gain_dB, openair0_cfg[0].rxg_mode[0],(int)openair0_cfg[0].rx_gain[0]);
#endif
#ifdef OAI_USRP
len += sprintf(&buffer[len], "[UE PROC] RX Gain %d dB\n",phy_vars_ue->rx_total_gain_dB);
#endif
len += sprintf(&buffer[len], "[UE_PROC] Frequency offset %d Hz (%d)\n",phy_vars_ue->lte_ue_common_vars.freq_offset,openair_daq_vars.freq_offset);
#if defined(EXMIMO) || defined(OAI_USRP)
len += sprintf(&buffer[len], "[UE_PROC] Frequency offset %d Hz (%d), estimated carrier frequency %f Hz\n",phy_vars_ue->lte_ue_common_vars.freq_offset,openair_daq_vars.freq_offset,openair0_cfg[0].rx_freq[0]-phy_vars_ue->lte_ue_common_vars.freq_offset);
#endif
len += sprintf(&buffer[len], "[UE PROC] UE mode = %s (%d)\n",mode_string[phy_vars_ue->UE_mode[0]],phy_vars_ue->UE_mode[0]);
len += sprintf(&buffer[len], "[UE PROC] timing_advance = %d\n",phy_vars_ue->timing_advance);
len += sprintf(&buffer[len], "[UE PROC] UE tx power = %d\n", PHY_vars_UE_g[0][0]->tx_power_dBm);
if (phy_vars_ue->UE_mode[0]==PUSCH) {
len += sprintf(&buffer[len], "[UE PROC] Po_PUSCH = %d dBm (PL %d dB, Po_NOMINAL_PUSCH %d dBm, PHR %d dB)\n",
PHY_vars_UE_g[0][0]->ulsch_ue[0]->Po_PUSCH,
get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,0),
mac_xface->get_Po_NOMINAL_PUSCH(phy_vars_ue->Mod_id,0),
PHY_vars_UE_g[0][0]->ulsch_ue[0]->PHR);
len += sprintf(&buffer[len], "[UE PROC] Po_PUCCH = %d dBm (Po_NOMINAL_PUCCH %d dBm, g_pucch %d dB)\n",
get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,0)+
phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
phy_vars_ue->dlsch_ue[0][0]->g_pucch,
phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
phy_vars_ue->dlsch_ue[0][0]->g_pucch);
}
//for (eNB=0;eNB<NUMBER_OF_eNB_MAX;eNB++) {
for (eNB=0; eNB<1; eNB++) {
len += sprintf(&buffer[len], "[UE PROC] RX spatial power eNB%d: [%d %d; %d %d] dB\n",
@@ -455,10 +476,8 @@ int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t
RRC_status = mac_UE_get_rrc_status(phy_vars_ue->Mod_id, 0);
len += sprintf(&buffer[len],"[UE PROC] RRC status = %d\n",RRC_status);
#endif
len += sprintf(&buffer[len],"[UE PROC] RSRP[0] %.2f dBm/RE, RSSI %.2f, RSRQ[0] %.2f\n",
10*log10(phy_vars_ue->PHY_measurements.rsrp[0])-phy_vars_ue->rx_total_gain_dB,
10*log10(phy_vars_ue->PHY_measurements.rssi)-phy_vars_ue->rx_total_gain_dB, 10*log10(phy_vars_ue->PHY_measurements.rsrq[0]));
len += sprintf(&buffer[len], "[UE PROC] Transmission Mode %d (mode1_flag %d)\n",phy_vars_ue->transmission_mode[eNB],phy_vars_ue->lte_frame_parms.mode1_flag);
len += sprintf(&buffer[len], "[UE PROC] PBCH err conseq %d, PBCH error total %d, PBCH FER %d\n",
phy_vars_ue->lte_ue_pbch_vars[eNB]->pdu_errors_conseq,
@@ -608,13 +627,18 @@ int dump_eNB_stats(PHY_VARS_eNB *phy_vars_eNB, char* buffer, int length)
if (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0) {
#endif
len += sprintf(&buffer[len],"[eNB PROC] UE %d (%x) Power: (%d,%d) dB, RSSI: (%d,%d) dBm, Sector %d\n",
len += sprintf(&buffer[len],"[eNB PROC] UE %d (%x) Power: (%d,%d) dB, Po_PUSCH: (%d,%d) dBm, Po_PUCCH (%d/%d) dBm, Po_PUCCH1 (%d,%d) dBm, PUCCH1 Thres %d dBm \n",
UE_id,
phy_vars_eNB->eNB_UE_stats[UE_id].crnti,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[UE_id]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[UE_id]->ulsch_power[1]),
phy_vars_eNB->eNB_UE_stats[UE_id].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[UE_id].UL_rssi[1],
dB_fixed(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH)-phy_vars_eNB->rx_total_gain_eNB_dB,
phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
dB_fixed(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_below)-phy_vars_eNB->rx_total_gain_eNB_dB,
dB_fixed(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_above)-phy_vars_eNB->rx_total_gain_eNB_dB,
PUCCH1_THRES+phy_vars_eNB->PHY_measurements_eNB[0].n0_power_tot_dBm, //-dB_fixed(phy_vars_eNB->lte_frame_parms.N_RB_UL),
phy_vars_eNB->eNB_UE_stats[UE_id].sector);
for(i=0; i<8; i++)
+11 -7
View File
@@ -48,7 +48,7 @@
* @{
*/
/** \fn free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch)
/** \fn free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch,unsigned char N_RB_DL)
\brief This function frees memory allocated for a particular DLSCH at eNB
@param dlsch Pointer to DLSCH to be removed
*/
@@ -74,9 +74,7 @@ void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch);
LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch);
LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t Mdlharq,uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch, uint8_t abstraction_flag);
@@ -754,7 +752,7 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t first_symbol_flag,
uint16_t nb_rb,
uint16_t pbch_pss_sss_adjust,
short **llr_save,
int16_t **llr_save,
uint8_t beamforming_mode);
/** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
@@ -875,6 +873,7 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param subframe Subframe number
@param vrb_type Flag to indicate distributed VRB type
@param high_speed_flag
@param frame_parms Pointer to frame descriptor
*/
@@ -1292,7 +1291,7 @@ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb);
@param vrb_type VRB type (0=localized,1=distributed)
@param rb_alloc_dci rballoc field from DCI
*/
uint32_t get_rballoc(uint8_t vrb_type,uint16_t rb_alloc_dci);
uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci);
/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type
@returns Transmission mode (1-7)
@@ -1401,7 +1400,8 @@ void ulsch_extract_rbs_single(int32_t **rxdataF,
uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,frame_t frame,uint8_t subframe);
uint8_t subframe2harq_pid_eNBrx(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
int generate_ue_dlsch_params_from_dci(uint8_t subframe,
int generate_ue_dlsch_params_from_dci(int frame,
uint8_t subframe,
void *dci_pdu,
rnti_t rnti,
DCI_format_t dci_format,
@@ -1412,7 +1412,8 @@ int generate_ue_dlsch_params_from_dci(uint8_t subframe,
uint16_t ra_rnti,
uint16_t p_rnti);
int32_t generate_eNB_dlsch_params_from_dci(uint8_t subframe,
int32_t generate_eNB_dlsch_params_from_dci(int frame,
uint8_t subframe,
void *dci_pdu,
rnti_t rnti,
DCI_format_t dci_format,
@@ -1822,5 +1823,8 @@ double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
uint8_t n_antenna_port,
LTE_UE_DLSCH_t *dlsch_ue);
*/
uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf);
/**@}*/
#endif
+104 -19
View File
@@ -442,10 +442,16 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
{
static int first_call=1;
LTE_eNB_COMMON *eNB_common_vars = &phy_vars_eNB->lte_eNB_common_vars;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
// PUCCH_CONFIG_DEDICATED *pucch_config_dedicated = &phy_vars_eNB->pucch_config_dedicated[UE_id];
int8_t sigma2_dB = phy_vars_eNB->PHY_measurements_eNB[0].n0_power_tot_dB;
int8_t sigma2_dB = phy_vars_eNB->PHY_measurements_eNB[0].n0_power_dB[0];
int32_t *Po_PUCCH = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH);
int32_t *Po_PUCCH_dBm = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH_dBm);
int32_t *Po_PUCCH1_below = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_below);
int32_t *Po_PUCCH1_above = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH1_above);
int32_t *Po_PUCCH_update = &(phy_vars_eNB->eNB_UE_stats[UE_id].Po_PUCCH_update);
uint32_t u,v,n,aa;
uint32_t z[12*14];
int16_t *zptr;
@@ -473,6 +479,34 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
if (first_call == 1) {
for (i=0;i<10;i++) {
for (j=0;j<NUMBER_OF_UE_MAX;j++) {
phy_vars_eNB->pucch1_stats_cnt[j][i]=0;
phy_vars_eNB->pucch1ab_stats_cnt[j][i]=0;
}
}
first_call=0;
}
/*
switch (frame_parms->N_RB_UL) {
case 6:
sigma2_dB -= 8;
break;
case 25:
sigma2_dB -= 14;
break;
case 50:
sigma2_dB -= 17;
break;
case 100:
sigma2_dB -= 20;
break;
default:
sigma2_dB -= 14;
}
*/
if ((deltaPUCCH_Shift==0) || (deltaPUCCH_Shift>3)) {
LOG_E(PHY,"[eNB] rx_pucch: Illegal deltaPUCCH_shift %d (should be 1,2,3)\n",deltaPUCCH_Shift);
@@ -493,7 +527,7 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
LOG_D(PHY,"[eNB] PUCCH: cNcs1/deltaPUCCH_Shift %d, Nprime %d, n1_pucch %d\n",thres,Nprime,n1_pucch);
#endif
N_UL_symb = (frame_parms->Ncp==0) ? 7 : 6;
N_UL_symb = (frame_parms->Ncp==NORMAL) ? 7 : 6;
if (n1_pucch < thres)
nprime0=n1_pucch;
@@ -536,6 +570,12 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
S=0; // 1
else
S=1; // j
/*
if (fmt==pucch_format1)
LOG_I(PHY,"[eNB] subframe %d => PUCCH1: u%d %d, v%d %d : ", subframe,ns&1,u,ns&1,v);
else
LOG_I(PHY,"[eNB] subframe %d => PUCCH1a/b: u%d %d, v%d %d : ", subframe,ns&1,u,ns&1,v);
*/
//loop over symbols in slot
for (l=0; l<N_UL_symb; l++) {
@@ -549,6 +589,7 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
}
refs=0;
// Comput W_noc(m) (36.211 p. 19)
@@ -573,11 +614,11 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
if (l<2) { // data
W_re=W4[n_oc][l];
W_im=0;
} else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==0)) { // reference and normal CP
} else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==NORMAL)) { // reference and normal CP
W_re=W3_re[n_oc][l-2];
W_im=W3_im[n_oc][l-2];
refs=1;
} else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==1)) { // reference and extended CP
} else if ((l<N_UL_symb-2)&&(frame_parms->Ncp==EXTENDED)) { // reference and extended CP
W_re=W4[n_oc][l-2];
W_im=0;
refs=1;
@@ -614,6 +655,7 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
LOG_D(PHY,"[eNB] PUCCH subframe %d z(%d,%d) => %d,%d, alpha(%d) => %d,%d\n",subframe,l,n,zptr[n<<1],zptr[(n<<1)+1],
alpha_ind,alpha_re[alpha_ind],alpha_im[alpha_ind]);
#endif
alpha_ind = (alpha_ind + n_cs)%12;
} // n
@@ -656,15 +698,15 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
rxptr = (int16_t *)&eNB_common_vars->rxdataF[0][aa][symbol_offset];
for (i=0; i<12; i++,j+=2,re_offset++) {
rxcomp[aa][j] = (int16_t)((rxptr[re_offset<<2]*(int32_t)zptr[j])>>15) - ((rxptr[1+(re_offset<<2)]*(int32_t)zptr[1+j])>>15);
rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<2]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<2)]*(int32_t)zptr[j])>>15);
rxcomp[aa][j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15) - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15);
rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15);
if (re_offset==frame_parms->ofdm_symbol_size)
re_offset = 0;
#ifdef DEBUG_PUCCH_RX
LOG_D(PHY,"[eNB] PUCCH subframe %d (%d,%d,%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,i,re_offset,m,j,
rxptr[re_offset<<2],rxptr[1+(re_offset<<2)],
rxptr[re_offset<<1],rxptr[1+(re_offset<<1)],
zptr[j],zptr[1+j],
rxcomp[aa][j],rxcomp[aa][1+j]);
#endif
@@ -718,29 +760,52 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
#endif
}
} //re
stat += (stat_re*stat_re) + (stat_im*stat_im);
} //re
} // aa
stat = (stat_re*stat_re) + (stat_im*stat_im);
if (stat>stat_max) {
stat_max = stat;
phase_max = phase;
}
#ifdef DEBUG_PUCCH_RX
LOG_D(PHY,"[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
#endif
} //phase
stat_max /= (nsymb*12); // normalize to energy per symbol and RE
#ifdef DEBUG_PUCCH_RX
LOG_D(PHY,"[eNB] PUCCH fmt0: stat_max : %d, sigma2_dB %d, phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,phase_max);
LOG_D(PHY,"[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
#endif
if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres)) //
#ifdef DEBUG_PUCCH_RX
LOG_D(PHY,"[eNB] PUCCH fmt0: stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,phy_vars_eNB->PHY_measurements_eNB[0].n0_power_tot_dBm,pucch1_thres,phase_max);
#endif
phy_vars_eNB->pucch1_stats[UE_id][(subframe<<10)+phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe]] = stat_max;
phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe] = (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe]+1)&1023;
/*
if (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe] == 0) {
write_output("pucch_debug.m","pucch_energy",
&phy_vars_eNB->pucch1_stats[UE_id][(subframe<<10)],
1024,1,2);
AssertFatal(0,"Exiting for PUCCH 1 debug\n");
}
*/
// This is a moving average of the PUCCH1 statistics conditioned on being above or below the threshold
if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres)) {
*payload = 1;
else
*Po_PUCCH1_above = ((*Po_PUCCH1_above<<9) + (stat_max<<9)+1024)>>10;
}
else {
*payload = 0;
*Po_PUCCH1_below = ((*Po_PUCCH1_below<<9) + (stat_max<<9)+1024)>>10;
}
LOG_D(PHY,"[eNB] PUCCH fmt0: stat_max : %d, sigma2_dB %d (I0 %d dBm, thres %d), Po_PUCCH1_below/above : %d / %d\n",dB_fixed(stat_max),sigma2_dB,phy_vars_eNB->PHY_measurements_eNB[0].n0_power_tot_dBm,pucch1_thres,dB_fixed(*Po_PUCCH1_below),dB_fixed(*Po_PUCCH1_above));
*Po_PUCCH_update = 1;
} else if ((fmt == pucch_format1a)||(fmt == pucch_format1b)) {
stat_max = 0;
@@ -816,17 +881,31 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
}
} //phase
stat_max/=(nsymb*12); //normalize to energy per symbol and RE
#ifdef DEBUG_PUCCH_RX
LOG_I(PHY,"[eNB] PUCCH fmt1: stat_max : %d, phase_max : %d\n",stat_max,phase_max);
#endif
// Do detection now
stat_re=0;
stat_im=0;
LOG_D(PHY,"PUCCH1A : Po_PUCCH before %d dB (%d)\n",dB_fixed(*Po_PUCCH),*Po_PUCCH);
*Po_PUCCH = ((*Po_PUCCH<<9) + (stat_max<<9)+1024)>>10;
*Po_PUCCH_dBm = dB_fixed(*Po_PUCCH) - phy_vars_eNB->rx_total_gain_eNB_dB;
*Po_PUCCH_update = 1;
LOG_D(PHY,"PUCCH1A : stat_max %d (%d,%d,%d) => Po_PUCCH %d\n",
dB_fixed(stat_max),
pucch1_thres+sigma2_dB,
pucch1_thres,
sigma2_dB,
dB_fixed(*Po_PUCCH));
// Do detection now
if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres)) {//
*Po_PUCCH = ((*Po_PUCCH*1023) + stat_max)>>10;
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
for (re=0; re<12; re++) {
chest_re=0;
@@ -928,8 +1007,14 @@ int32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
} // aa
#ifdef DEBUG_PUCCH_RX
LOG_I(PHY,"stat %d,%d\n",stat_re,stat_im);
LOG_D(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im,
(subframe<<10) + (phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe]));
#endif
((int16_t*)&phy_vars_eNB->pucch1ab_stats[UE_id][(subframe<<10) + (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe])])[0] = stat_re;
((int16_t*)&phy_vars_eNB->pucch1ab_stats[UE_id][(subframe<<10) + (phy_vars_eNB->pucch1_stats_cnt[UE_id][subframe])])[1] = stat_im;
phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe] = (phy_vars_eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
*payload = (stat_re<0) ? 1 : 0;
if (fmt==pucch_format1b)
+14 -8
View File
@@ -248,13 +248,15 @@ int rx_sss(PHY_VARS_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_
(frame_parms->symbols_per_tti/2)-2, // second to last symbol of
0, // slot 0
phy_vars_ue->rx_offset,
0);
0,
1);
// PSS
slot_fep(phy_vars_ue,
(frame_parms->symbols_per_tti/2)-1, // last symbol of
0, // slot 0
phy_vars_ue->rx_offset,
0);
0,
1);
} else { // TDD
#ifdef DEBUG_SSS
if (phy_vars_ue->lte_frame_parms.Ncp == NORMAL)
@@ -268,13 +270,15 @@ int rx_sss(PHY_VARS_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_
(frame_parms->symbols_per_tti>>1)-1, // last symbol of
1, // slot 1
phy_vars_ue->rx_offset,
0);
0,
1);
// PSS
slot_fep(phy_vars_ue,
2, // symbol 2 of
2, // slot 2
phy_vars_ue->rx_offset,
0);
0,
1);
}
pss_sss_extract(phy_vars_ue,
@@ -303,26 +307,28 @@ int rx_sss(PHY_VARS_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uint8_
(frame_parms->symbols_per_tti/2)-2,
10,
phy_vars_ue->rx_offset,
0);
0,1);
// PSS
slot_fep(phy_vars_ue,
(frame_parms->symbols_per_tti/2)-1,
10,
phy_vars_ue->rx_offset,
0);
0,1);
} else { // TDD
// SSS
slot_fep(phy_vars_ue,
(frame_parms->symbols_per_tti>>1)-1,
11,
phy_vars_ue->rx_offset,
0);
0,
1);
// PSS
slot_fep(phy_vars_ue,
2,
12,
phy_vars_ue->rx_offset,
0);
0,
1);
}
pss_sss_extract(phy_vars_ue,
+6 -2
View File
@@ -298,10 +298,14 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
ulsch_harq = ulsch->harq_processes[harq_pid];
if (harq_pid==255) {
LOG_E(PHY, "ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n");
return(-1);
LOG_E(PHY, "FATAL ERROR: illegal harq_pid, returning\n");
return -1;
}
if (ulsch_harq->Nsymb_pusch == 0) {
LOG_E(PHY, "FATAL ERROR: harq_pid %d, Nsymb 0!\n",harq_pid);
return 1+ulsch->max_turbo_iterations;
}
if (llr8_flag == 0)
tc = phy_threegpplte_turbo_decoder16;
else
+368 -72
View File
@@ -52,15 +52,19 @@
//extern int **ulchmag_eren;
//eren
static short jitter[8] __attribute__ ((aligned(16))) = {1,0,0,1,0,1,1,0};
static short jitterc[8] __attribute__ ((aligned(16))) = {0,1,1,0,1,0,0,1};
#ifndef OFDMA_ULSCH
void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i idft_in128[3][1200],idft_out128[3][1200];
__m128i norm128;
#elif defined(__arm__)
int16x8_t idft_in128[3][1200],idft_out128[3][1200];
int16x8_t norm128;
#endif
int16_t *idft_in0=(int16_t*)idft_in128[0],*idft_out0=(int16_t*)idft_out128[0];
int16_t *idft_in1=(int16_t*)idft_in128[1],*idft_out1=(int16_t*)idft_out128[1];
int16_t *idft_in2=(int16_t*)idft_in128[2],*idft_out2=(int16_t*)idft_out128[2];
@@ -68,7 +72,7 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
uint32_t *z0,*z1,*z2,*z3,*z4,*z5,*z6,*z7,*z8,*z9,*z10=NULL,*z11=NULL;
int i,ip;
__m128i norm128;
// printf("Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
@@ -108,6 +112,7 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
// conjugate input
for (i=0; i<(Msc_PUSCH>>2); i++) {
#if defined(__x86_64__)||defined(__i386__)
*&(((__m128i*)z0)[i])=_mm_sign_epi16(*&(((__m128i*)z0)[i]),*(__m128i*)&conjugate2[0]);
*&(((__m128i*)z1)[i])=_mm_sign_epi16(*&(((__m128i*)z1)[i]),*(__m128i*)&conjugate2[0]);
*&(((__m128i*)z2)[i])=_mm_sign_epi16(*&(((__m128i*)z2)[i]),*(__m128i*)&conjugate2[0]);
@@ -119,10 +124,29 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
*&(((__m128i*)z8)[i])=_mm_sign_epi16(*&(((__m128i*)z8)[i]),*(__m128i*)&conjugate2[0]);
*&(((__m128i*)z9)[i])=_mm_sign_epi16(*&(((__m128i*)z9)[i]),*(__m128i*)&conjugate2[0]);
if (frame_parms->Ncp==0) {
if (frame_parms->Ncp==NORMAL) {
*&(((__m128i*)z10)[i])=_mm_sign_epi16(*&(((__m128i*)z10)[i]),*(__m128i*)&conjugate2[0]);
*&(((__m128i*)z11)[i])=_mm_sign_epi16(*&(((__m128i*)z11)[i]),*(__m128i*)&conjugate2[0]);
}
#elif defined(__arm__)
*&(((int16x8_t*)z0)[i])=vmulq_s16(*&(((int16x8_t*)z0)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z1)[i])=vmulq_s16(*&(((int16x8_t*)z1)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z2)[i])=vmulq_s16(*&(((int16x8_t*)z2)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z3)[i])=vmulq_s16(*&(((int16x8_t*)z3)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z4)[i])=vmulq_s16(*&(((int16x8_t*)z4)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z5)[i])=vmulq_s16(*&(((int16x8_t*)z5)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z6)[i])=vmulq_s16(*&(((int16x8_t*)z6)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z7)[i])=vmulq_s16(*&(((int16x8_t*)z7)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z8)[i])=vmulq_s16(*&(((int16x8_t*)z8)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z9)[i])=vmulq_s16(*&(((int16x8_t*)z9)[i]),*(int16x8_t*)&conjugate2[0]);
if (frame_parms->Ncp==NORMAL) {
*&(((int16x8_t*)z10)[i])=vmulq_s16(*&(((int16x8_t*)z10)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z11)[i])=vmulq_s16(*&(((int16x8_t*)z11)[i]),*(int16x8_t*)&conjugate2[0]);
}
#endif
}
for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
@@ -150,23 +174,21 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
dft12((int16_t *)idft_in1,(int16_t *)idft_out1);
dft12((int16_t *)idft_in2,(int16_t *)idft_out2);
/*
dft12f(&((__m128i *)idft_in0)[0],&((__m128i *)idft_in0)[1],&((__m128i *)idft_in0)[2],&((__m128i *)idft_in0)[3],&((__m128i *)idft_in0)[4],&((__m128i *)idft_in0)[5],&((__m128i *)idft_in0)[6],&((__m128i *)idft_in0)[7],&((__m128i *)idft_in0)[8],&((__m128i *)idft_in0)[9],&((__m128i *)idft_in0)[10],&((__m128i *)idft_in0)[11],
&((__m128i *)idft_out0)[0],&((__m128i *)idft_out0)[1],&((__m128i *)idft_out0)[2],&((__m128i *)idft_out0)[3],&((__m128i *)idft_out0)[4],&((__m128i *)idft_out0)[5],&((__m128i *)idft_out0)[6],&((__m128i *)idft_out0)[7],&((__m128i *)idft_out0)[8],&((__m128i *)idft_out0)[9],&((__m128i *)idft_out0)[10],&((__m128i *)idft_out0)[11]);
dft12f(&((__m128i *)idft_in1)[0],&((__m128i *)idft_in1)[1],&((__m128i *)idft_in1)[2],&((__m128i *)idft_in1)[3],&((__m128i *)idft_in1)[4],&((__m128i *)idft_in1)[5],&((__m128i *)idft_in1)[6],&((__m128i *)idft_in1)[7],&((__m128i *)idft_in1)[8],&((__m128i *)idft_in1)[9],&((__m128i *)idft_in1)[10],&((__m128i *)idft_in1)[11],
&((__m128i *)idft_out1)[0],&((__m128i *)idft_out1)[1],&((__m128i *)idft_out1)[2],&((__m128i *)idft_out1)[3],&((__m128i *)idft_out1)[4],&((__m128i *)idft_out1)[5],&((__m128i *)idft_out1)[6],&((__m128i *)idft_out1)[7],&((__m128i *)idft_out1)[8],&((__m128i *)idft_out1)[9],&((__m128i *)idft_out1)[10],&((__m128i *)idft_out1)[11]);
dft12f(&((__m128i *)idft_in2)[0],&((__m128i *)idft_in2)[1],&((__m128i *)idft_in2)[2],&((__m128i *)idft_in2)[3],&((__m128i *)idft_in2)[4],&((__m128i *)idft_in2)[5],&((__m128i *)idft_in2)[6],&((__m128i *)idft_in2)[7],&((__m128i *)idft_in2)[8],&((__m128i *)idft_in2)[9],&((__m128i *)idft_in2)[10],&((__m128i *)idft_in2)[11],
&((__m128i *)idft_out2)[0],&((__m128i *)idft_out2)[1],&((__m128i *)idft_out2)[2],&((__m128i *)idft_out2)[3],&((__m128i *)idft_out2)[4],&((__m128i *)idft_out2)[5],&((__m128i *)idft_out2)[6],&((__m128i *)idft_out2)[7],&((__m128i *)idft_out2)[8],&((__m128i *)idft_out2)[9],&((__m128i *)idft_out2)[10],&((__m128i *)idft_out2)[11]);
*/
#if defined(__x86_64__)||defined(__i386__)
norm128 = _mm_set1_epi16(9459);
#elif defined(__arm__)
norm128 = vdupq_n_s16(9459);
#endif
for (i=0; i<12; i++) {
#if defined(__x86_64__)||defined(__i386__)
((__m128i*)idft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)idft_out0)[i],norm128),1);
((__m128i*)idft_out1)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)idft_out1)[i],norm128),1);
((__m128i*)idft_out2)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)idft_out2)[i],norm128),1);
#elif defined(__arm__)
((int16x8_t*)idft_out0)[i] = vqdmulhq_s16(((int16x8_t*)idft_out0)[i],norm128);
((int16x8_t*)idft_out1)[i] = vqdmulhq_s16(((int16x8_t*)idft_out1)[i],norm128);
((int16x8_t*)idft_out2)[i] = vqdmulhq_s16(((int16x8_t*)idft_out2)[i],norm128);
#endif
}
break;
@@ -363,6 +385,10 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
dft1200(idft_in2,idft_out2,1);
break;
default:
// should not be reached
LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
return;
}
@@ -394,6 +420,7 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
// conjugate output
for (i=0; i<(Msc_PUSCH>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
((__m128i*)z0)[i]=_mm_sign_epi16(((__m128i*)z0)[i],*(__m128i*)&conjugate2[0]);
((__m128i*)z1)[i]=_mm_sign_epi16(((__m128i*)z1)[i],*(__m128i*)&conjugate2[0]);
((__m128i*)z2)[i]=_mm_sign_epi16(((__m128i*)z2)[i],*(__m128i*)&conjugate2[0]);
@@ -405,12 +432,36 @@ void lte_idft(LTE_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH)
((__m128i*)z8)[i]=_mm_sign_epi16(((__m128i*)z8)[i],*(__m128i*)&conjugate2[0]);
((__m128i*)z9)[i]=_mm_sign_epi16(((__m128i*)z9)[i],*(__m128i*)&conjugate2[0]);
if (frame_parms->Ncp==0) {
if (frame_parms->Ncp==NORMAL) {
((__m128i*)z10)[i]=_mm_sign_epi16(((__m128i*)z10)[i],*(__m128i*)&conjugate2[0]);
((__m128i*)z11)[i]=_mm_sign_epi16(((__m128i*)z11)[i],*(__m128i*)&conjugate2[0]);
}
#elif defined(__arm__)
*&(((int16x8_t*)z0)[i])=vmulq_s16(*&(((int16x8_t*)z0)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z1)[i])=vmulq_s16(*&(((int16x8_t*)z1)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z2)[i])=vmulq_s16(*&(((int16x8_t*)z2)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z3)[i])=vmulq_s16(*&(((int16x8_t*)z3)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z4)[i])=vmulq_s16(*&(((int16x8_t*)z4)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z5)[i])=vmulq_s16(*&(((int16x8_t*)z5)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z6)[i])=vmulq_s16(*&(((int16x8_t*)z6)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z7)[i])=vmulq_s16(*&(((int16x8_t*)z7)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z8)[i])=vmulq_s16(*&(((int16x8_t*)z8)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z9)[i])=vmulq_s16(*&(((int16x8_t*)z9)[i]),*(int16x8_t*)&conjugate2[0]);
if (frame_parms->Ncp==NORMAL) {
*&(((int16x8_t*)z10)[i])=vmulq_s16(*&(((int16x8_t*)z10)[i]),*(int16x8_t*)&conjugate2[0]);
*&(((int16x8_t*)z11)[i])=vmulq_s16(*&(((int16x8_t*)z11)[i]),*(int16x8_t*)&conjugate2[0]);
}
#endif
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
#endif
@@ -425,10 +476,15 @@ int32_t ulsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb,
int16_t **llrp)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int32_t i;
__m128i **llrp128 = (__m128i **)llrp;
#elif defined(__arm__)
int16x8_t *rxF= (int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int16x8_t **llrp128 = (int16x8_t **)llrp;
#endif
int i;
// printf("qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),llr128U-(__m128i*)ulsch_llr);
@@ -439,8 +495,10 @@ int32_t ulsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
(*llrp128)++;
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
return(0);
@@ -454,41 +512,64 @@ void ulsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb,
int16_t **llrp)
{
int i;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *ch_mag;
__m128i mmtmpU0;
__m128i **llrp128=(__m128i **)llrp;
int32_t i;
// uint8_t symbol_mod;
// printf("ulsch_rx.c: ulsch_16qam_llr: symbol %d\n",symbol);
// symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
ch_mag =(__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
#elif defined(__arm__)
int16x8_t *rxF=(int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int16x8_t *ch_mag;
int16x8_t xmm0;
int16_t **llrp16=llrp;
ch_mag =(int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
#endif
for (i=0; i<(nb_rb*3); i++) {
#if defined(__x86_64__) || defined(__i386__)
mmtmpU0 = _mm_abs_epi16(rxF[i]);
// print_shorts("tmp0",&tmp0);
mmtmpU0 = _mm_subs_epi16(ch_mag[i],mmtmpU0);
(*llrp128)[0] = _mm_unpacklo_epi32(rxF[i],mmtmpU0);
(*llrp128)[1] = _mm_unpackhi_epi32(rxF[i],mmtmpU0);
(*llrp128)+=2;
#elif defined(__arm__)
xmm0 = vabsq_s16(rxF[i]);
xmm0 = vqsubq_s16(ch_mag[i],xmm0);
(*llrp16)[0] = vgetq_lane_s16(rxF[i],0);
(*llrp16)[1] = vgetq_lane_s16(xmm0,0);
(*llrp16)[2] = vgetq_lane_s16(rxF[i],1);
(*llrp16)[3] = vgetq_lane_s16(xmm0,1);
(*llrp16)[4] = vgetq_lane_s16(rxF[i],2);
(*llrp16)[5] = vgetq_lane_s16(xmm0,2);
(*llrp16)[6] = vgetq_lane_s16(rxF[i],2);
(*llrp16)[7] = vgetq_lane_s16(xmm0,3);
(*llrp16)[8] = vgetq_lane_s16(rxF[i],4);
(*llrp16)[9] = vgetq_lane_s16(xmm0,4);
(*llrp16)[10] = vgetq_lane_s16(rxF[i],5);
(*llrp16)[11] = vgetq_lane_s16(xmm0,5);
(*llrp16)[12] = vgetq_lane_s16(rxF[i],6);
(*llrp16)[13] = vgetq_lane_s16(xmm0,6);
(*llrp16)[14] = vgetq_lane_s16(rxF[i],7);
(*llrp16)[15] = vgetq_lane_s16(xmm0,7);
(*llrp16)+=16;
#endif
// print_bytes("rxF[i]",&rxF[i]);
// print_bytes("rxF[i+1]",&rxF[i+1]);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
@@ -501,27 +582,29 @@ void ulsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint16_t nb_rb,
int16_t **llrp)
{
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *ch_mag,*ch_magb;
int32_t i;
__m128i mmtmpU1,mmtmpU2;
int i;
int32_t **llrp32=(int32_t **)llrp;
// uint8_t symbol_mod;
// symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
#if defined(__x86_64__) || defined(__i386)
__m128i *rxF=(__m128i*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
__m128i *ch_mag,*ch_magb;
__m128i mmtmpU1,mmtmpU2;
ch_mag =(__m128i*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
ch_magb =(__m128i*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)];
#elif defined(__arm__)
int16x8_t *rxF=(int16x8_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
int16x8_t *ch_mag,*ch_magb;
int16x8_t mmtmpU1,mmtmpU2;
ch_mag =(int16x8_t*)&ul_ch_mag[0][(symbol*frame_parms->N_RB_DL*12)];
ch_magb =(int16x8_t*)&ul_ch_magb[0][(symbol*frame_parms->N_RB_DL*12)];
#endif
// printf("symbol %d: mag %d, magb %d\n",symbol,_mm_extract_epi16(ch_mag[0],0),_mm_extract_epi16(ch_magb[0],0));
for (i=0; i<(nb_rb*3); i++) {
#if defined(__x86_64__) || defined(__i386__)
mmtmpU1 = _mm_abs_epi16(rxF[i]);
mmtmpU1 = _mm_subs_epi16(ch_mag[i],mmtmpU1);
@@ -541,12 +624,34 @@ void ulsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
(*llrp32)[9] = _mm_extract_epi32(rxF[i],3);
(*llrp32)[10] = _mm_extract_epi32(mmtmpU1,3);
(*llrp32)[11] = _mm_extract_epi32(mmtmpU2,3);
#elif defined(__arm__)
mmtmpU1 = vabsq_s16(rxF[i]);
mmtmpU1 = vqsubq_s16(ch_mag[i],mmtmpU1);
mmtmpU2 = vabsq_s16(mmtmpU1);
mmtmpU2 = vqsubq_s16(ch_magb[i],mmtmpU2);
(*llrp32)[0] = vgetq_lane_s32((int32x4_t)rxF[i],0);
(*llrp32)[1] = vgetq_lane_s32((int32x4_t)mmtmpU1,0);
(*llrp32)[2] = vgetq_lane_s32((int32x4_t)mmtmpU2,0);
(*llrp32)[3] = vgetq_lane_s32((int32x4_t)rxF[i],1);
(*llrp32)[4] = vgetq_lane_s32((int32x4_t)mmtmpU1,1);
(*llrp32)[5] = vgetq_lane_s32((int32x4_t)mmtmpU2,1);
(*llrp32)[6] = vgetq_lane_s32((int32x4_t)rxF[i],2);
(*llrp32)[7] = vgetq_lane_s32((int32x4_t)mmtmpU1,2);
(*llrp32)[8] = vgetq_lane_s32((int32x4_t)mmtmpU2,2);
(*llrp32)[9] = vgetq_lane_s32((int32x4_t)rxF[i],3);
(*llrp32)[10] = vgetq_lane_s32((int32x4_t)mmtmpU1,3);
(*llrp32)[11] = vgetq_lane_s32((int32x4_t)mmtmpU2,3);
#endif
(*llrp32)+=12;
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
@@ -558,13 +663,20 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
{
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b;
__m128i *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b;
#elif defined(__arm__)
int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b;
int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b;
#endif
int32_t i;
if (frame_parms->nb_antennas_rx>1) {
#if defined(__x86_64__) || defined(__i386__)
rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128_0 = (__m128i *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
@@ -578,15 +690,31 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
ul_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0[i],1),_mm_srai_epi16(ul_ch_mag128_1[i],1));
ul_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0b[i],1),_mm_srai_epi16(ul_ch_mag128_1b[i],1));
rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i*)&jitterc[0]));
}
// remove any bias (DC component after IDFT)
// ((uint32_t*)rxdataF_comp128_0)[0]=0;
#elif defined(__arm__)
rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128_0 = (int16x8_t *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128_1 = (int16x8_t *)&ul_ch_mag[1][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128_0b = (int16x8_t *)&ul_ch_magb[0][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128_1b = (int16x8_t *)&ul_ch_magb[1][symbol*frame_parms->N_RB_DL*12];
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation)
for (i=0; i<nb_rb*3; i++) {
rxdataF_comp128_0[i] = vhaddq_s16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
ul_ch_mag128_0[i] = vhaddq_s16(ul_ch_mag128_0[i],ul_ch_mag128_1[i]);
ul_ch_mag128_0b[i] = vhaddq_s16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]);
rxdataF_comp128_0[i] = vqaddq_s16(rxdataF_comp128_0[i],(*(int16x8_t*)&jitterc[0]));
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void ulsch_extract_rbs_single(int32_t **rxdataF,
@@ -643,9 +771,6 @@ void ulsch_extract_rbs_single(int32_t **rxdataF,
}
}
_mm_empty();
_m_empty();
}
void ulsch_correct_ext(int32_t **rxdataF_ext,
@@ -683,42 +808,81 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
{
uint16_t rb;
#if defined(__x86_64__) || defined(__i386__)
__m128i *ul_ch128,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128;
uint8_t aarx;//,symbol_mod;
__m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3;
#ifdef OFDMA_ULSCH
__m128i QAM_amp128U,QAM_amp128bU;
#endif
// symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
// printf("comp: symbol %d\n",symbol);
#elif defined(__arm__)
#ifdef ULSCH_OFDMA
int16x4_t *ul_ch128,*rxdataF128;
int16x8_t *ul_ch_mag128,*ul_ch_mag128b,*rxdataF_comp128;
uint8_t aarx;//,symbol_mod;
int32x4_t mmtmpU0,mmtmpU1,mmtmpU0b,mmtmpU1b;
#ifdef OFDMA_ULSCH
int16x8_t mmtmpU2,mmtmpU3;
int16x8_t QAM_amp128U,QAM_amp128bU;
#endif
int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1};
int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift);
#endif
#ifdef OFDMA_ULSCH
#if defined(__x86_64__) || defined(__i386__)
if (Qm == 4)
QAM_amp128U = _mm_set1_epi16(QAM16_n1);
else if (Qm == 6) {
QAM_amp128U = _mm_set1_epi16(QAM64_n1);
QAM_amp128bU = _mm_set1_epi16(QAM64_n2);
}
#elif defined(__arm__)
if (Qm == 4)
QAM_amp128U = vdupq_n_s16(QAM16_n1);
else if (Qm == 6) {
QAM_amp128U = vdupq_n_s16(QAM64_n1);
QAM_amp128bU = vdupq_n_s16(QAM64_n2);
}
#endif
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128 = (__m128i *)&ul_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128b = (__m128i *)&ul_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];
#elif defined(__arm__)
ul_ch128 = (int16x4_t *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128 = (int16x8_t *)&ul_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12];
ul_ch_mag128b = (int16x8_t *)&ul_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF128 = (int16x4_t *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12];
rxdataF_comp128 = (int16x8_t *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12];
#endif
for (rb=0; rb<nb_rb; rb++) {
// printf("comp: symbol %d rb %d\n",symbol,rb);
#ifdef OFDMA_ULSCH
if (Qm>2) {
// get channel amplitude if not QPSK
#if defined(__x86_64__) || defined(__i386__)
mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
@@ -757,10 +921,36 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
ul_ch_mag128b[2] = _mm_mulhi_epi16(ul_ch_mag128b[2],QAM_amp128bU);
ul_ch_mag128b[2] = _mm_slli_epi16(ul_ch_mag128b[2],2);// 2 to compensate the scale channel estimate
#elif defined(__arm__)
mmtmpU0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[1], ul_ch128[1]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
mmtmpU2 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[2], ul_ch128[2]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[3], ul_ch128[3]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
mmtmpU3 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[4], ul_ch128[4]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[5], ul_ch128[5]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
mmtmpU4 = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
ul_ch_mag128b[0] = vqdmulhq_s16(mmtmpU2,QAM_amp128b);
ul_ch_mag128b[1] = vqdmulhq_s16(mmtmpU3,QAM_amp128b);
ul_ch_mag128[0] = vqdmulhq_s16(mmtmpU2,QAM_amp128);
ul_ch_mag128[1] = vqdmulhq_s16(mmtmpU3,QAM_amp128);
ul_ch_mag128b[2] = vqdmulhq_s16(mmtmpU4,QAM_amp128b);
ul_ch_mag128[2] = vqdmulhq_s16(mmtmpU4,QAM_amp128);
#endif
}
#else
#else // SC-FDMA
// just compute channel magnitude without scaling, this is done after equalization for SC-FDMA
#if defined(__x86_64__) || defined(__i386__)
mmtmpU0 = _mm_madd_epi16(ul_ch128[0],ul_ch128[0]);
mmtmpU0 = _mm_srai_epi32(mmtmpU0,output_shift);
@@ -780,8 +970,29 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
ul_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpU1,mmtmpU1);
// printf("comp: symbol %d rb %d => %d,%d,%d (output_shift %d)\n",symbol,rb,*((int16_t*)&ul_ch_mag128[0]),*((int16_t*)&ul_ch_mag128[1]),*((int16_t*)&ul_ch_mag128[2]),output_shift);
#elif defined(__arm__)
mmtmpU0 = vmull_s16(ul_ch128[0], ul_ch128[0]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[1], ul_ch128[1]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
ul_ch_mag128[0] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[2], ul_ch128[2]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[3], ul_ch128[3]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
ul_ch_mag128[1] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[4], ul_ch128[4]);
mmtmpU0 = vqshlq_s32(vqaddq_s32(mmtmpU0,vrev64q_s32(mmtmpU0)),-output_shift128);
mmtmpU1 = vmull_s16(ul_ch128[5], ul_ch128[5]);
mmtmpU1 = vqshlq_s32(vqaddq_s32(mmtmpU1,vrev64q_s32(mmtmpU1)),-output_shift128);
ul_ch_mag128[2] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
#endif
#endif
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpU0);
@@ -853,21 +1064,81 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
ul_ch_mag128b+=3;
rxdataF128+=3;
rxdataF_comp128+=3;
#elif defined(__arm__)
mmtmpU0 = vmull_s16(ul_ch128[0], rxdataF128[0]);
//mmtmpU0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
mmtmpU1 = vmull_s16(ul_ch128[1], rxdataF128[1]);
//mmtmpU1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
mmtmpU0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpU0),vget_high_s32(mmtmpU0)),
vpadd_s32(vget_low_s32(mmtmpU1),vget_high_s32(mmtmpU1)));
//mmtmpU0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
mmtmpU0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]);
//mmtmpU0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
mmtmpU1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]);
//mmtmpU0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmpU1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpU0b),vget_high_s32(mmtmpU0b)),
vpadd_s32(vget_low_s32(mmtmpU1b),vget_high_s32(mmtmpU1b)));
//mmtmpU1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
mmtmpU0 = vqshlq_s32(mmtmpU0,-output_shift128);
mmtmpU1 = vqshlq_s32(mmtmpU1,-output_shift128);
rxdataF_comp128[0] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[2], rxdataF128[2]);
mmtmpU1 = vmull_s16(ul_ch128[3], rxdataF128[3]);
mmtmpU0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpU0),vget_high_s32(mmtmpU0)),
vpadd_s32(vget_low_s32(mmtmpU1),vget_high_s32(mmtmpU1)));
mmtmpU0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]);
mmtmpU1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]);
mmtmpU1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpU0b),vget_high_s32(mmtmpU0b)),
vpadd_s32(vget_low_s32(mmtmpU1b),vget_high_s32(mmtmpU1b)));
mmtmpU0 = vqshlq_s32(mmtmpU0,-output_shift128);
mmtmpU1 = vqshlq_s32(mmtmpU1,-output_shift128);
rxdataF_comp128[1] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
mmtmpU0 = vmull_s16(ul_ch128[4], rxdataF128[4]);
mmtmpU1 = vmull_s16(ul_ch128[5], rxdataF128[5]);
mmtmpU0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpU0),vget_high_s32(mmtmpU0)),
vpadd_s32(vget_low_s32(mmtmpU1),vget_high_s32(mmtmpU1)));
mmtmpU0b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]);
mmtmpU1b = vmull_s16(vrev32_s16(vmul_s16(ul_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]);
mmtmpU1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpU0b),vget_high_s32(mmtmpU0b)),
vpadd_s32(vget_low_s32(mmtmpU1b),vget_high_s32(mmtmpU1b)));
mmtmpU0 = vqshlq_s32(mmtmpU0,-output_shift128);
mmtmpU1 = vqshlq_s32(mmtmpU1,-output_shift128);
rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1));
// Add a jitter to compensate for the saturation in "packs" resulting in a bias on the DC after IDFT
rxdataF_comp128[0] = vqaddq_s16(rxdataF_comp128[0],(*(int16x8_t*)&jitter[0]));
rxdataF_comp128[1] = vqaddq_s16(rxdataF_comp128[1],(*(int16x8_t*)&jitter[0]));
rxdataF_comp128[2] = vqaddq_s16(rxdataF_comp128[2],(*(int16x8_t*)&jitter[0]));
ul_ch128+=6;
ul_ch_mag128+=3;
ul_ch_mag128b+=3;
rxdataF128+=6;
rxdataF_comp128+=3;
#endif
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
#if defined(__x86_64__) || defined(__i386__)
__m128i QAM_amp128U_0,QAM_amp128bU_0,QAM_amp128U_1,QAM_amp128bU_1;
#endif
void ulsch_channel_compensation_alamouti(int32_t **rxdataF_ext, // For Distributed Alamouti Combining
int32_t **ul_ch_estimates_ext_0,
@@ -884,7 +1155,7 @@ void ulsch_channel_compensation_alamouti(int32_t **rxdataF_ext,
uint16_t nb_rb,
uint8_t output_shift)
{
#if defined(__x86_64__) || defined(__i386__)
uint16_t rb;
__m128i *ul_ch128_0,*ul_ch128_1,*ul_ch_mag128_0,*ul_ch_mag128_1,*ul_ch_mag128b_0,*ul_ch_mag128b_1,*rxdataF128,*rxdataF_comp128_0,*rxdataF_comp128_1;
uint8_t aarx;//,symbol_mod;
@@ -1152,7 +1423,7 @@ void ulsch_channel_compensation_alamouti(int32_t **rxdataF_ext,
_mm_empty();
_m_empty();
#endif
}
@@ -1172,6 +1443,7 @@ void ulsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti
uint16_t nb_rb)
{
#if defined(__x86_64__) || defined(__i386__)
int16_t *rxF,*rxF0,*rxF1;
__m128i *ch_mag,*ch_magb,*ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b;
uint8_t rb,re,aarx;
@@ -1227,13 +1499,18 @@ void ulsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,// For Distributed Alamouti
_mm_empty();
_m_empty();
#endif
}
#if defined(__x86_64__) || defined(__i386__)
__m128i avg128U;
#elif defined(__arm__)
int32x4_t avg128U;
#endif
void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
LTE_DL_FRAME_PARMS *frame_parms,
@@ -1243,11 +1520,14 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
int16_t rb;
uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *ul_ch128;
#elif defined(__arm__)
int16x4_t *ul_ch128;
#endif
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
//clear average level
#if defined(__x86_64__) || defined(__i386__)
avg128U = _mm_setzero_si128();
ul_ch128=(__m128i *)drs_ch_estimates_ext[aarx];
@@ -1259,33 +1539,44 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
ul_ch128+=3;
if (rb==0) {
// print_shorts("ul_ch128",&ul_ch128[0]);
// print_shorts("ul_ch128",&ul_ch128[1]);
// print_shorts("ul_ch128",&ul_ch128[2]);
}
}
#elif defined(__arm__)
avg128U = vdupq_n_s32(0);
ul_ch128=(int16x4_t *)drs_ch_estimates_ext[aarx];
for (rb=0; rb<nb_rb; rb++) {
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[0],ul_ch128[0]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[1],ul_ch128[1]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[2],ul_ch128[2]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[3],ul_ch128[3]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[4],ul_ch128[4]));
avg128U = vqaddq_s32(avg128U,vmull_s16(ul_ch128[5],ul_ch128[5]));
ul_ch128+=6;
}
#endif
DevAssert( nb_rb );
avg[aarx] = (((int*)&avg128U)[0] +
((int*)&avg128U)[1] +
((int*)&avg128U)[2] +
((int*)&avg128U)[3])/(nb_rb*12);
// printf("Channel level : %d\n",avg[aarx]);
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
int32_t avgU[2];
int32_t avgU_0[2],avgU_1[2]; // For the Distributed Alamouti Scheme
/* --> moved to LTE_eNB_PUSCH structure
int32_t ulsch_power[2];
int32_t ulsch_power_0[2],ulsch_power_1[2];// For the distributed Alamouti Scheme
*/
void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB,
uint32_t sched_subframe,
@@ -1325,6 +1616,11 @@ void rx_ulsch(PHY_VARS_eNB *phy_vars_eNB,
rx_power_correction = 1;
if (ulsch[UE_id]->harq_processes[harq_pid]->nb_rb == 0) {
LOG_E(PHY,"PUSCH (%d/%x) nb_rb=0!\n", harq_pid,ulsch[UE_id]->rnti,harq_pid);
return;
}
for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active); l++) {
#ifdef DEBUG_ULSCH
+19 -4
View File
@@ -49,12 +49,15 @@
//#define DEBUG_ULSCH_MODULATION
__m128i dft_in128[4][1200],dft_in128[4][1200],dft_out128[4][1200],dft_out128[4][1200];
#ifndef OFDMA_ULSCH
void dft_lte(mod_sym_t *z,mod_sym_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i dft_in128[4][1200],dft_out128[4][1200];
#elif defined(__arm__)
int16x8_t dft_in128[4][1200],dft_out128[4][1200];
#endif
uint32_t *dft_in0=(uint32_t*)dft_in128[0],*dft_out0=(uint32_t*)dft_out128[0];
uint32_t *dft_in1=(uint32_t*)dft_in128[1],*dft_out1=(uint32_t*)dft_out128[1];
uint32_t *dft_in2=(uint32_t*)dft_in128[2],*dft_out2=(uint32_t*)dft_out128[2];
@@ -64,8 +67,11 @@ void dft_lte(mod_sym_t *z,mod_sym_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
uint32_t *z0,*z1,*z2,*z3,*z4,*z5,*z6,*z7,*z8,*z9,*z10,*z11;
uint32_t i,ip;
#if defined(__x86_64__) || defined(__i386__)
__m128i norm128;
#elif defined(__arm__)
int16x8_t norm128;
#endif
// msg("Doing lte_dft for Msc_PUSCH %d\n",Msc_PUSCH);
d0 = (uint32_t *)d;
@@ -119,12 +125,21 @@ void dft_lte(mod_sym_t *z,mod_sym_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
dft12f(&((__m128i *)dft_in2)[0],&((__m128i *)dft_in2)[1],&((__m128i *)dft_in2)[2],&((__m128i *)dft_in2)[3],&((__m128i *)dft_in2)[4],&((__m128i *)dft_in2)[5],&((__m128i *)dft_in2)[6],&((__m128i *)dft_in2)[7],&((__m128i *)dft_in2)[8],&((__m128i *)dft_in2)[9],&((__m128i *)dft_in2)[10],&((__m128i *)dft_in2)[11],
&((__m128i *)dft_out2)[0],&((__m128i *)dft_out2)[1],&((__m128i *)dft_out2)[2],&((__m128i *)dft_out2)[3],&((__m128i *)dft_out2)[4],&((__m128i *)dft_out2)[5],&((__m128i *)dft_out2)[6],&((__m128i *)dft_out2)[7],&((__m128i *)dft_out2)[8],&((__m128i *)dft_out2)[9],&((__m128i *)dft_out2)[10],&((__m128i *)dft_out2)[11]);
*/
#if defined(__x86_64__) || defined(__i386__)
norm128 = _mm_set1_epi16(9459);
#elif defined(__arm__)
norm128 = vdupq_n_s16(9459);
#endif
for (i=0; i<12; i++) {
#if defined(__x86_64__) || defined(__i386__)
((__m128i*)dft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out0)[i],norm128),1);
((__m128i*)dft_out1)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out1)[i],norm128),1);
((__m128i*)dft_out2)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out2)[i],norm128),1);
#elif defined(__arm__)
((int16x8_t*)dft_out0)[i] = vqdmulhq_s16(((int16x8_t*)dft_out0)[i],norm128);
((int16x8_t*)dft_out1)[i] = vqdmulhq_s16(((int16x8_t*)dft_out1)[i],norm128);
((int16x8_t*)dft_out2)[i] = vqdmulhq_s16(((int16x8_t*)dft_out2)[i],norm128);
#endif
}
break;
+3 -1
View File
@@ -62,13 +62,15 @@ void PHY_ofdm_mod(int *input,
\param Ns Slot number (0..19)
\param sample_offset offset within rxdata (points to beginning of subframe)
\param no_prefix if 1 prefix is removed by HW
\param reset_freq_est if non-zero it resets the frequency offset estimation loop
*/
int slot_fep(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
unsigned char Ns,
int sample_offset,
int no_prefix);
int no_prefix,
int reset_freq_est);
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
+6 -28
View File
@@ -33,22 +33,13 @@
#define SOFFSET 0
void rescale(int16_t *input,int length)
{
__m128i *input128 = (__m128i *)input;
int i;
for (i=0; i<length>>2; i++) {
input128[i] = _mm_srai_epi16(input128[i],4);
}
}
int slot_fep(PHY_VARS_UE *phy_vars_ue,
unsigned char l,
unsigned char Ns,
int sample_offset,
int no_prefix)
int no_prefix,
int reset_freq_est)
{
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
@@ -145,18 +136,11 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
memcpy((void *)tmp_dft_in,
(void *)&ue_common_vars->rxdata[aa][(rx_offset-nb_prefix_samples0) % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
#ifdef OAI_USRP
rescale((int16_t *)tmp_dft_in,
frame_parms->ofdm_symbol_size);
#endif
dft((int16_t *)tmp_dft_in,
(int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
start_meas(&phy_vars_ue->rx_dft_stats);
#ifdef OAI_USRP
rescale((int16_t *)&ue_common_vars->rxdata[aa][(rx_offset-nb_prefix_samples0) % frame_length_samples],
frame_parms->ofdm_symbol_size+nb_prefix_samples0);
#endif
dft((int16_t *)&ue_common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
stop_meas(&phy_vars_ue->rx_dft_stats);
@@ -183,17 +167,10 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
memcpy((void *)tmp_dft_in,
(void *)&ue_common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
frame_parms->ofdm_symbol_size*sizeof(int));
#ifdef OAI_USRP
rescale((int16_t *)tmp_dft_in,
frame_parms->ofdm_symbol_size);
#endif
dft((int16_t *)tmp_dft_in,
(int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
} else { // use dft input from RX buffer directly
#ifdef OAI_USRP
rescale((int16_t *)&ue_common_vars->rxdata[aa][(rx_offset-nb_prefix_samples) % frame_length_samples],
frame_parms->ofdm_symbol_size+nb_prefix_samples);
#endif
dft((int16_t *)&ue_common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
(int16_t *)&ue_common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
}
@@ -241,7 +218,8 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
lte_est_freq_offset(ue_common_vars->dl_ch_estimates[0],
frame_parms,
l,
&ue_common_vars->freq_offset);
&ue_common_vars->freq_offset,
reset_freq_est);
stop_meas(&phy_vars_ue->dlsch_freq_offset_estimation_stats);
}
+75 -375
View File
@@ -48,7 +48,13 @@ void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t slot)
uint16_t len;
uint32_t *kHz7_5ptr;
#if defined(__x86_64__) || defined(__i386__)
__m128i *txptr128,*kHz7_5ptr128,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2;
#elif defined(__arm__)
int16x8_t *txptr128,*kHz7_5ptr128;
int32x4_t mmtmp_re,mmtmp_im;
int32x4_t mmtmp0,mmtmp1;
#endif
uint32_t slot_offset;
// uint8_t aa;
uint32_t i;
@@ -90,13 +96,17 @@ void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t slot)
// slot_offset += (len/4);
len = phy_vars_ue->lte_frame_parms.samples_per_tti/2;
//for (aa=0;aa<phy_vars_ue->lte_frame_parms.nb_antennas_tx;aa++) {
#if defined(__x86_64__) || defined(__i386__)
txptr128 = (__m128i *)&txdata[slot_offset];
kHz7_5ptr128 = (__m128i *)kHz7_5ptr;
#elif defined(__arm__)
txptr128 = (int16x8_t*)&txdata[slot_offset];
kHz7_5ptr128 = (int16x8_t*)kHz7_5ptr;
#endif
// apply 7.5 kHz
// if (((slot>>1)&1) == 0) { // apply the sinusoid from the table directly
for (i=0; i<(len>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
mmtmp_re = _mm_madd_epi16(*txptr128,*kHz7_5ptr128);
// Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work)
mmtmp_im = _mm_shufflelo_epi16(*kHz7_5ptr128,_MM_SHUFFLE(2,3,0,1));
@@ -107,39 +117,32 @@ void apply_7_5_kHz(PHY_VARS_UE *phy_vars_ue,int32_t*txdata,uint8_t slot)
mmtmp_im = _mm_srai_epi32(mmtmp_im,15);
mmtmp_re2 = _mm_unpacklo_epi32(mmtmp_re,mmtmp_im);
mmtmp_im2 = _mm_unpackhi_epi32(mmtmp_re,mmtmp_im);
/*
printf("%d: (%d,%d) (%d,%d) (%d,%d) (%d,%d) x (%d,%d) (%d,%d) (%d,%d) (%d,%d) => ",
i,
((short*)txptr128)[0],
((short*)txptr128)[1],
((short*)txptr128)[2],
((short*)txptr128)[3],
((short*)txptr128)[4],
((short*)txptr128)[5],
((short*)txptr128)[6],
((short*)txptr128)[7],
((short*)kHz7_5ptr128)[0],
((short*)kHz7_5ptr128)[1],
((short*)kHz7_5ptr128)[2],
((short*)kHz7_5ptr128)[3],
((short*)kHz7_5ptr128)[4],
((short*)kHz7_5ptr128)[5],
((short*)kHz7_5ptr128)[6],
((short*)kHz7_5ptr128)[7]);*/
txptr128[0] = _mm_packs_epi32(mmtmp_re2,mmtmp_im2);
/* printf("%(%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
((short*)txptr128)[0],
((short*)txptr128)[1],
((short*)txptr128)[2],
((short*)txptr128)[3],
((short*)txptr128)[4],
((short*)txptr128)[5],
((short*)txptr128)[6],
((short*)txptr128)[7]);*/
txptr128++;
kHz7_5ptr128++;
#elif defined(__arm__)
mmtmp0 = vmull_s16(((int16x4_t*)txptr128)[0],((int16x4_t*)kHz7_5ptr128)[0]);
//mmtmp0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
mmtmp1 = vmull_s16(((int16x4_t*)txptr128)[1],((int16x4_t*)kHz7_5ptr128)[1]);
//mmtmp1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
//mmtmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)txptr128)[0],*(int16x4_t*)conjugate75_2)),((int16x4_t*)kHz7_5ptr128)[0]);
//mmtmp0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)txptr128)[1],*(int16x4_t*)conjugate75_2)), ((int16x4_t*)kHz7_5ptr128)[1]);
//mmtmp0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
//mmtmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
txptr128[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
txptr128++;
kHz7_5ptr128++;
#endif
}
//}
@@ -154,7 +157,14 @@ void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t slot)
int32_t **rxdata_7_5kHz=phy_vars_eNB->lte_eNB_common_vars.rxdata_7_5kHz[0];
uint16_t len;
uint32_t *kHz7_5ptr;
#if defined(__x86_64__) || defined(__i386__)
__m128i *rxptr128,*rxptr128_7_5kHz,*kHz7_5ptr128,kHz7_5_2,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2;
#elif defined(__arm__)
int16x8_t *rxptr128,*kHz7_5ptr128,*rxptr128_7_5kHz;
int32x4_t mmtmp_re,mmtmp_im;
int32x4_t mmtmp0,mmtmp1;
#endif
uint32_t slot_offset,slot_offset2;
uint8_t aa;
uint32_t i;
@@ -199,14 +209,21 @@ void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t slot)
for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) {
#if defined(__x86_64__) || defined(__i386__)
rxptr128 = (__m128i *)&rxdata[aa][slot_offset];
rxptr128_7_5kHz = (__m128i *)&rxdata_7_5kHz[aa][slot_offset2];
kHz7_5ptr128 = (__m128i *)kHz7_5ptr;
#elif defined(__arm__)
rxptr128 = (int16x8_t *)&rxdata[aa][slot_offset];
rxptr128_7_5kHz = (int16x8_t *)&rxdata_7_5kHz[aa][slot_offset2];
kHz7_5ptr128 = (int16x8_t *)kHz7_5ptr;
#endif
// apply 7.5 kHz
// if (((slot>>1)&1) == 0) { // apply the sinusoid from the table directly
for (i=0; i<(len>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
kHz7_5_2 = _mm_sign_epi16(*kHz7_5ptr128,*(__m128i*)&conjugate75_2[0]);
mmtmp_re = _mm_madd_epi16(*rxptr128,kHz7_5_2);
// Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work)
@@ -223,350 +240,33 @@ void remove_7_5_kHz(PHY_VARS_eNB *phy_vars_eNB,uint8_t slot)
rxptr128++;
rxptr128_7_5kHz++;
kHz7_5ptr128++;
#elif defined(__arm__)
kHz7_5ptr128[0] = vmulq_s16(kHz7_5ptr128[0],((int16x8_t*)conjugate75_2)[0]);
mmtmp0 = vmull_s16(((int16x4_t*)rxptr128)[0],((int16x4_t*)kHz7_5ptr128)[0]);
//mmtmp0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])]
mmtmp1 = vmull_s16(((int16x4_t*)rxptr128)[1],((int16x4_t*)kHz7_5ptr128)[1]);
//mmtmp1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])]
mmtmp_re = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
//mmtmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
mmtmp0 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)rxptr128)[0],*(int16x4_t*)conjugate75_2)), ((int16x4_t*)kHz7_5ptr128)[0]);
//mmtmp0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
mmtmp1 = vmull_s16(vrev32_s16(vmul_s16(((int16x4_t*)rxptr128)[1],*(int16x4_t*)conjugate75_2)), ((int16x4_t*)kHz7_5ptr128)[1]);
//mmtmp1 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
mmtmp_im = vcombine_s32(vpadd_s32(vget_low_s32(mmtmp0),vget_high_s32(mmtmp0)),
vpadd_s32(vget_low_s32(mmtmp1),vget_high_s32(mmtmp1)));
//mmtmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
rxptr128_7_5kHz[0] = vcombine_s16(vmovn_s32(mmtmp_re),vmovn_s32(mmtmp_im));
rxptr128_7_5kHz++;
rxptr128++;
kHz7_5ptr128++;
#endif
}
}
}
void apply_625_Hz(PHY_VARS_UE *phy_vars_ue,int16_t *prach)
{
uint32_t *Hz625ptr;
__m128i *txptr128,*Hz625ptr128,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2;
uint8_t aa;
uint32_t Ncp,len;
uint32_t i;
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->lte_frame_parms;
uint8_t frame_type = phy_vars_ue->lte_frame_parms.frame_type;
uint8_t prach_ConfigIndex = phy_vars_ue->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
switch (prach_fmt) {
case 0:
Ncp = 3168;
break;
case 1:
case 3:
Ncp = 21024;
break;
case 2:
Ncp = 6240;
break;
case 4:
Ncp = 448;
break;
default:
Ncp = 3168;
break;
}
switch (frame_parms->N_RB_UL) {
case 6:
Hz625ptr = (uint32_t*)sig625_1_25MHz;
len = 1536 + (Ncp>>4);
break;
case 15:
Hz625ptr = (uint32_t*)sig625_2_5MHz;
len = 3072 + (Ncp>>3);
break;
case 25:
Hz625ptr = (uint32_t*)sig625_5MHz;
len = 6144+(Ncp>>2);
break;
case 50:
Hz625ptr = (uint32_t*)sig625_10MHz;
len = 12288+(Ncp>>1);
break;
case 75:
Hz625ptr = (uint32_t*)sig625_15MHz;
len = 18432+((2*Ncp)/3);
break;
case 100:
Hz625ptr = (uint32_t*)sig625_20MHz;
len = 24576+Ncp;
break;
default:
Hz625ptr = (uint32_t*)sig625_5MHz;
len = 6144+(Ncp>>2);
break;
}
for (aa=0; aa<phy_vars_ue->lte_frame_parms.nb_antennas_tx; aa++) {
txptr128 = (__m128i *)prach;
Hz625ptr128 = (__m128i *)Hz625ptr;
// apply 7.5 kHz
// if (((slot>>1)&1) == 0) { // apply the sinusoid from the table directly
for (i=0; i<(len>>2); i++) {
mmtmp_re = _mm_madd_epi16(*txptr128,*Hz625ptr128);
// Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work)
mmtmp_im = _mm_shufflelo_epi16(*Hz625ptr128,_MM_SHUFFLE(2,3,0,1));
mmtmp_im = _mm_shufflehi_epi16(mmtmp_im,_MM_SHUFFLE(2,3,0,1));
mmtmp_im = _mm_sign_epi16(mmtmp_im,*(__m128i*)&conjugate75[0]);
mmtmp_im = _mm_madd_epi16(mmtmp_im,txptr128[0]);
mmtmp_re = _mm_srai_epi32(mmtmp_re,15);
mmtmp_im = _mm_srai_epi32(mmtmp_im,15);
mmtmp_re2 = _mm_unpacklo_epi32(mmtmp_re,mmtmp_im);
mmtmp_im2 = _mm_unpackhi_epi32(mmtmp_re,mmtmp_im);
/*
printf("%d: (%d,%d) (%d,%d) (%d,%d) (%d,%d) x (%d,%d) (%d,%d) (%d,%d) (%d,%d) => ",
i,
((short*)txptr128)[0],
((short*)txptr128)[1],
((short*)txptr128)[2],
((short*)txptr128)[3],
((short*)txptr128)[4],
((short*)txptr128)[5],
((short*)txptr128)[6],
((short*)txptr128)[7],
((short*)Hz625ptr128)[0],
((short*)Hz625ptr128)[1],
((short*)Hz625ptr128)[2],
((short*)Hz625ptr128)[3],
((short*)Hz625ptr128)[4],
((short*)Hz625ptr128)[5],
((short*)Hz625ptr128)[6],
((short*)Hz625ptr128)[7]);*/
txptr128[0] = _mm_packs_epi32(mmtmp_re2,mmtmp_im2);
/* printf("%(%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
((short*)txptr128)[0],
((short*)txptr128)[1],
((short*)txptr128)[2],
((short*)txptr128)[3],
((short*)txptr128)[4],
((short*)txptr128)[5],
((short*)txptr128)[6],
((short*)txptr128)[7]);*/
txptr128++;
Hz625ptr128++;
}
}
}
void remove_625_Hz(PHY_VARS_eNB *phy_vars_eNB,int16_t *prach)
{
uint32_t *Hz625ptr;
__m128i *txptr128,*Hz625ptr128,Hz625_2,mmtmp_re,mmtmp_im,mmtmp_re2,mmtmp_im2;
uint8_t aa;
uint32_t i,Ncp,len;
LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms;
uint8_t frame_type = frame_parms->frame_type;
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
switch (prach_fmt) {
case 0:
Ncp = 3168;
break;
case 1:
case 3:
Ncp = 21024;
break;
case 2:
Ncp = 6240;
break;
case 4:
Ncp = 448;
break;
default:
Ncp = 3168;
break;
}
switch (frame_parms->N_RB_UL) {
case 6:
Hz625ptr = (uint32_t*)sig625_1_25MHz;
len = 1536 + (Ncp>>4);
break;
case 15:
Hz625ptr = (uint32_t*)sig625_2_5MHz;
len = 3072 + (Ncp>>3) ;
break;
case 25:
Hz625ptr = (uint32_t*)sig625_5MHz;
len = 6144+(Ncp>>2);
break;
case 50:
Hz625ptr = (uint32_t*)sig625_10MHz;
len = 12288+(Ncp>>1);
break;
case 75:
Hz625ptr = (uint32_t*)sig625_15MHz;
len = 18432+((2*Ncp)/3);
break;
case 100:
Hz625ptr = (uint32_t*)sig625_20MHz;
len = 24576+Ncp;
break;
default:
Hz625ptr = (uint32_t*)sig625_5MHz;
len = 11400;
break;
}
for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) {
txptr128 = (__m128i *)prach;
Hz625ptr128 = (__m128i *)Hz625ptr;
// apply 7.5 kHz
// if (((slot>>1)&1) == 0) { // apply the sinusoid from the table directly
for (i=0; i<(len>>2); i++) {
Hz625_2 = _mm_sign_epi16(*Hz625ptr128,*(__m128i*)&conjugate75_2[0]);
mmtmp_re = _mm_madd_epi16(*txptr128,Hz625_2);
// Real part of complex multiplication (note: 7_5kHz signal is conjugated for this to work)
mmtmp_im = _mm_shufflelo_epi16(Hz625_2,_MM_SHUFFLE(2,3,0,1));
mmtmp_im = _mm_shufflehi_epi16(mmtmp_im,_MM_SHUFFLE(2,3,0,1));
mmtmp_im = _mm_sign_epi16(mmtmp_im,*(__m128i*)&conjugate75[0]);
mmtmp_im = _mm_madd_epi16(mmtmp_im,txptr128[0]);
mmtmp_re = _mm_srai_epi32(mmtmp_re,15);
mmtmp_im = _mm_srai_epi32(mmtmp_im,15);
mmtmp_re2 = _mm_unpacklo_epi32(mmtmp_re,mmtmp_im);
mmtmp_im2 = _mm_unpackhi_epi32(mmtmp_re,mmtmp_im);
/*
printf("%d: (%d,%d) (%d,%d) (%d,%d) (%d,%d) x (%d,%d) (%d,%d) (%d,%d) (%d,%d) => ",
i,
((short*)txptr128)[0],
((short*)txptr128)[1],
((short*)txptr128)[2],
((short*)txptr128)[3],
((short*)txptr128)[4],
((short*)txptr128)[5],
((short*)txptr128)[6],
((short*)txptr128)[7],
((short*)Hz625ptr128)[0],
((short*)Hz625ptr128)[1],
((short*)Hz625ptr128)[2],
((short*)Hz625ptr128)[3],
((short*)Hz625ptr128)[4],
((short*)Hz625ptr128)[5],
((short*)Hz625ptr128)[6],
((short*)Hz625ptr128)[7]);*/
txptr128[0] = _mm_packs_epi32(mmtmp_re2,mmtmp_im2);
/* printf("%(%d,%d) (%d,%d) (%d,%d) (%d,%d)\n",
((short*)txptr128)[0],
((short*)txptr128)[1],
((short*)txptr128)[2],
((short*)txptr128)[3],
((short*)txptr128)[4],
((short*)txptr128)[5],
((short*)txptr128)[6],
((short*)txptr128)[7]);*/
txptr128++;
Hz625ptr128++;
}
}
}
void init_prach625(LTE_DL_FRAME_PARMS *frame_parms)
{
uint32_t len,i,Ncp;
double fs;
int16_t *Hz625ptr;
uint8_t frame_type = frame_parms->frame_type;
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
switch (prach_fmt) {
case 0:
Ncp = 3168;
break;
case 1:
case 3:
Ncp = 21024;
break;
case 2:
Ncp = 6240;
break;
case 4:
Ncp = 448;
break;
default:
Ncp = 3168;
break;
}
switch (frame_parms->N_RB_UL) {
case 6:
len = 1536 + (Ncp>>4);
fs = 1920000.0;
Hz625ptr = sig625_1_25MHz;
break;
case 15:
len = 3072 + (Ncp>>3) ;
fs = 3840000.0;
Hz625ptr = sig625_2_5MHz;
break;
case 25:
len = 6144+(Ncp>>2);
fs = 7680000.0;
Hz625ptr = sig625_5MHz;
break;
case 50:
len = 12288+(Ncp>>1);
fs = 15360000.0;
Hz625ptr = sig625_10MHz;
break;
case 75:
len = 18432+((2*Ncp)/3);
fs = 23040000.0;
Hz625ptr = sig625_15MHz;
break;
case 100:
len = 24576+Ncp;
fs = 30720000.0;
Hz625ptr = sig625_20MHz;
break;
default:
len = 6144+(Ncp>>2);
fs = 7680000.0;
Hz625ptr = sig625_5MHz;
break;
}
for (i=0; i<len; i++) {
Hz625ptr[i<<1] = (int16_t)floor(32767.0*cos(2*M_PI*625*i/fs));
Hz625ptr[1+(i<<1)] = (int16_t)floor(32767.0*sin(2*M_PI*625*i/fs));
// printf("prach625 %d: (%d,%d)\n",i,Hz625ptr[i<<1],Hz625ptr[1+(i<<1)]);
}
}
+4 -1
View File
@@ -1,5 +1,8 @@
lte_dfts: lte_dfts.c
gcc -O3 -msse4.1 -o lte_dfts lte_dfts.c fft.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS
gcc -O2 -mavx2 -g -ggdb -o lte_dfts lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS
lte_dfts.s: lte_dfts.c
gcc -O2 -mavx2 -S lte_dfts.c time_meas.c file_output.c ../../SIMULATION/TOOLS/taus.c -I$$OPENAIR1_DIR -I$$OPENAIR_TARGETS -I$$OPENAIR2_DIR/COMMON -DUSER_MODE -DMR_MAIN -DNB_ANTENNAS_RX=1 # -DD256STATS #-DD64STATS
dft_cycles: lte_dfts
./lte_dfts | egrep cycles
-15
View File
@@ -28,7 +28,6 @@
*******************************************************************************/
#include "defs.h"
#ifndef EXPRESSMIMO_TARGET
static __m128i alpha_128 __attribute__ ((aligned(16)));
static __m128i shift __attribute__ ((aligned(16)));
@@ -169,17 +168,3 @@ main ()
}
#endif //MAIN
#else //EXPRESSMIMO_TARGET
int add_cpx_vector(short *x,
short *alpha,
short *y,
unsigned int N)
{
}
#endif //EXPRESSMIMO_TARGET
-15
View File
@@ -28,7 +28,6 @@
*******************************************************************************/
#include "defs.h"
#ifndef EXPRESSMIMO_TARGET
int add_vector16(short *x,
short *y,
@@ -286,17 +285,3 @@ main ()
}
#endif //MAIN
#else //EXPRESSMIMO_TARGET
/*
int add_vector16(short *x,
short *y,
short *z,
unsigned int N)
{
}
*/
#endif // EXPRESSMIMO_TARGET
+47 -2
View File
@@ -43,10 +43,12 @@ int32_t dot_product(int16_t *x,
uint8_t output_shift)
{
uint32_t n;
#if defined(__x86_64__) || defined(__i386__)
__m128i *x128,*y128,mmtmp1,mmtmp2,mmtmp3,mmcumul,mmcumul_re,mmcumul_im;
__m64 mmtmp7;
__m128i minus_i = _mm_set_epi16(-1,1,-1,1,-1,1,-1,1);
uint32_t n;
int32_t result;
x128 = (__m128i*) x;
@@ -113,11 +115,54 @@ int32_t dot_product(int16_t *x,
// convert back to integer
result = _mm_cvtsi64_si32(mmtmp7);
return(result);
_mm_empty();
_m_empty();
#elif defined(__arm__)
int16x4_t *x_128=(int16x4_t*)x;
int16x4_t *y_128=(int16x4_t*)y;
int32x4_t tmp_re,tmp_im;
int32x4_t tmp_re1,tmp_im1;
int32x4_t re_cumul,im_cumul;
int32x2_t re_cumul2,im_cumul2;
int32x4_t shift = vdupq_n_s32(-output_shift);
int32x2x2_t result2;
int16_t conjug[4]__attribute__((aligned(16))) = {-1,1,-1,1} ;
return(result);
re_cumul = vdupq_n_s32(0);
im_cumul = vdupq_n_s32(0);
for (n=0; n<(N>>2); n++) {
tmp_re = vmull_s16(*x_128++, *y_128++);
//tmp_re = [Re(x[0])Re(y[0]) Im(x[0])Im(y[0]) Re(x[1])Re(y[1]) Im(x[1])Im(y[1])]
tmp_re1 = vmull_s16(*x_128++, *y_128++);
//tmp_re1 = [Re(x1[1])Re(x2[1]) Im(x1[1])Im(x2[1]) Re(x1[1])Re(x2[2]) Im(x1[1])Im(x2[2])]
tmp_re = vcombine_s32(vpadd_s32(vget_low_s32(tmp_re),vget_high_s32(tmp_re)),
vpadd_s32(vget_low_s32(tmp_re1),vget_high_s32(tmp_re1)));
//tmp_re = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2]) Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])]
tmp_im = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
//tmp_im = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])]
tmp_im1 = vmull_s16(vrev32_s16(vmul_s16(*x_128++,*(int16x4_t*)conjug)),*y_128++);
//tmp_im1 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])]
tmp_im = vcombine_s32(vpadd_s32(vget_low_s32(tmp_im),vget_high_s32(tmp_im)),
vpadd_s32(vget_low_s32(tmp_im1),vget_high_s32(tmp_im1)));
//tmp_im = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])]
re_cumul = vqaddq_s32(re_cumul,vqshlq_s32(tmp_re,shift));
im_cumul = vqaddq_s32(im_cumul,vqshlq_s32(tmp_im,shift));
}
re_cumul2 = vpadd_s32(vget_low_s32(re_cumul),vget_high_s32(re_cumul));
im_cumul2 = vpadd_s32(vget_low_s32(im_cumul),vget_high_s32(im_cumul));
re_cumul2 = vpadd_s32(re_cumul2,re_cumul2);
im_cumul2 = vpadd_s32(im_cumul2,im_cumul2);
result2 = vzip_s32(re_cumul2,im_cumul2);
return(vget_lane_s32(result2.val[0],0));
#endif
}
+100 -255
View File
@@ -29,9 +29,27 @@
#include "PHY/sse_intrin.h"
#include "defs.h"
#ifndef EXPRESSMIMO_TARGET
static __m128i alpha_128 __attribute__ ((aligned(16)));
static __m128i shift __attribute__ ((aligned(16)));
#if defined(__x86_64__) || defined(__i386__)
#define simd_q15_t __m128i
#define simdshort_q15_t __m64
#define shiftright_int16(a,shift) _mm_srai_epi16(a,shift)
#define set1_int16(a) _mm_set1_epi16(a)
#define mulhi_int16(a,b) _mm_slli_epi16(_mm_mulhi_epi16(a,b),1)
#define mulhi_s1_int16(a,b) _mm_slli_epi16(_mm_mulhi_epi16(a,b),2)
#define adds_int16(a,b) _mm_adds_epi16(a,b)
#define mullo_int16(a,b) _mm_mullo_epi16(a,b)
#elif defined(__arm__)
#define simd_q15_t int16x8_t
#define simdshort_q15_t int16x4_t
#define shiftright_int16(a,shift) vshrq_n_s16(a,shift)
#define set1_int16(a) vdupq_n_s16(a)
#define mulhi_int16(a,b) vqdmulhq_s16(a,b)
#define mulhi_s1_int16(a,b) vshlq_n_s16(vqdmulhq_s16(a,b),1)
#define adds_int16(a,b) vqaddq_s16(a,b)
#define mullo_int16(a,b) vmulq_s16(a,b)
#define _mm_empty()
#define _m_empty()
#endif
void multadd_complex_vector_real_scalar(int16_t *x,
@@ -41,19 +59,19 @@ void multadd_complex_vector_real_scalar(int16_t *x,
uint32_t N)
{
__m128i alpha_128,*x_128=(__m128i*)x,*y_128=(__m128i*)y;
simd_q15_t alpha_128,*x_128=(simd_q15_t *)x,*y_128=(simd_q15_t*)y;
int n;
alpha_128 = _mm_set1_epi16(alpha);
alpha_128 = set1_int16(alpha);
if (zero_flag == 1)
for (n=0; n<N>>2; n++) {
y_128[n] = _mm_slli_epi16(_mm_mulhi_epi16(x_128[n],alpha_128),1);
y_128[n] = mulhi_int16(x_128[n],alpha_128);
}
else
for (n=0; n<N>>2; n++) {
y_128[n] = _mm_adds_epi16(y_128[n],_mm_slli_epi16(_mm_mulhi_epi16(x_128[n],alpha_128),1));
y_128[n] = adds_int16(y_128[n],mulhi_int16(x_128[n],alpha_128));
}
_mm_empty();
@@ -69,32 +87,33 @@ void multadd_real_vector_complex_scalar(int16_t *x,
uint32_t i;
// do 8 multiplications at a time
__m128i alpha_r_128,alpha_i_128,yr,yi,*x_128=(__m128i*)x,*y_128=(__m128i*)y;
simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x,*y_128=(simd_q15_t*)y;
int j;
// printf("alpha = %d,%d\n",alpha[0],alpha[1]);
alpha_r_128 = _mm_set_epi16(alpha[0],alpha[0],alpha[0],alpha[0],alpha[0],alpha[0],alpha[0],alpha[0]);
alpha_i_128 = _mm_set_epi16(alpha[1],alpha[1],alpha[1],alpha[1],alpha[1],alpha[1],alpha[1],alpha[1]);
alpha_r_128 = set1_int16(alpha[0]);
alpha_i_128 = set1_int16(alpha[1]);
j=0;
for (i=0; i<N>>3; i++) {
yr = _mm_slli_epi16(_mm_mulhi_epi16(alpha_r_128,x_128[i]),2);
yi = _mm_slli_epi16(_mm_mulhi_epi16(alpha_i_128,x_128[i]),2);
// print_shorts("yr",&yr);
// print_shorts("yi",&yi);
yr = mulhi_s1_int16(alpha_r_128,x_128[i]);
yi = mulhi_s1_int16(alpha_i_128,x_128[i]);
#if defined(__x86_64__) || defined(__i386__)
y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpacklo_epi16(yr,yi));
// print_shorts("y",&y_128[j]);
j++;
y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpackhi_epi16(yr,yi));
// print_shorts("y",&y_128[j]);
j++;
#elif defined(__arm__)
int16x8x2_t yint;
yint = vzipq_s16(yr,yi);
y_128[j] = adds_int16(y_128[j],yint.val[0]);
j++;
y_128[j] = adds_int16(y_128[j],yint.val[1]);
j++;
#endif
}
_mm_empty();
@@ -102,6 +121,7 @@ void multadd_real_vector_complex_scalar(int16_t *x,
}
/*
int rotate_cpx_vector(int16_t *x,
int16_t *alpha,
int16_t *y,
@@ -127,23 +147,10 @@ int rotate_cpx_vector(int16_t *x,
register __m128i m0,m1;
// short *temps;
// int *tempd;
__m128i *x_128;
__m128i *y_128;
// __m128i temp;
/*
msg("rotate_cpx_vector: %x,%x,%x,%d,%d\n",
x,
alpha,
y,
N,
output_shift);
*/
shift = _mm_cvtsi32_si128(output_shift);
@@ -177,111 +184,44 @@ int rotate_cpx_vector(int16_t *x,
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>3); i++) {
// printf("i=%d\n",i);
/*
temps = (short *)x_128;
printf("x1 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
temps = (int16_t *)&alpha_128;
printf("alpha : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
*/
m0 = _mm_madd_epi16(x_128[0],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
/*
temp = m0;
tempd = &temp;
printf("m0 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
*/
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
/*
temp = m0;
tempd = (int *)&temp;
printf("m0 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
*/
m1=m0;
m0 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[0] = _mm_unpacklo_epi32(m0,m0); // 1- pack in a 128 bit register [re im re im]
// temps = (int16_t *)&y_128[0];
// printf("y0 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
m0 = _mm_madd_epi16(x_128[1],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1 = m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[1] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
m0 = _mm_madd_epi16(x_128[2],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1 = m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[2] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
m0 = _mm_madd_epi16(x_128[3],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1 = m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[3] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e
// print_shorts(y_128[0],"y_128[0]=");
y_128[0] = _mm_shufflelo_epi16(y_128[0],0x1e);
y_128[0] = _mm_shufflehi_epi16(y_128[0],0x1e);
((int16_t*)&y_128[0])[1] = -((int16_t*)&y_128[0])[1];
((int16_t*)&y_128[0])[5] = -((int16_t*)&y_128[0])[5];
// print_shorts(y_128[0],"y_128[0]=");
// print_shorts(y_128[1],"y_128[1]=");
y_128[1] = _mm_shufflelo_epi16(y_128[1],0x1e);
y_128[1] = _mm_shufflehi_epi16(y_128[1],0x1e);
((int16_t*)&y_128[1])[1] = -((int16_t*)&y_128[1])[1];
((int16_t*)&y_128[1])[5] = -((int16_t*)&y_128[1])[5];
// print_shorts(y_128[1],"y_128[1]=");
// print_shorts(y_128[2],"y_128[2]=");
y_128[2] = _mm_shufflelo_epi16(y_128[2],0x1e);
y_128[2] = _mm_shufflehi_epi16(y_128[2],0x1e);
((int16_t*)&y_128[2])[1] = -((int16_t*)&y_128[2])[1];
((int16_t*)&y_128[2])[5] = -((int16_t*)&y_128[2])[5];
// print_shorts(y_128[2],"y_128[2]=");
// print_shorts(y_128[3],"y_128[3]=");
y_128[3] = _mm_shufflelo_epi16(y_128[3],0x1e);
y_128[3] = _mm_shufflehi_epi16(y_128[3],0x1e);
((int16_t*)&y_128[3])[1] = -((int16_t*)&y_128[3])[1];
((int16_t*)&y_128[3])[5] = -((int16_t*)&y_128[3])[5];
// print_shorts(y_128[3],"y_128[3]=");
}
@@ -326,16 +266,6 @@ int rotate_cpx_vector2(int16_t *x,
__m128i *y_128;
/*
printf("rotate_cpx_vector2: %x,%x,%x,%d,%d\n",
x,
alpha,
y,
N,
output_shift);
*/
shift = _mm_cvtsi32_si128(output_shift);
x_128 = (__m128i *)&x[0];
@@ -361,51 +291,22 @@ int rotate_cpx_vector2(int16_t *x,
y_128 = (__m128i *)&y[0];
// _mm_empty();
// return(0);
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>1); i++) {
// temps = (short *)&x_128[i];
// printf("x1 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
// temps = (short *)&alpha_128;
// printf("x2 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
m0 = _mm_madd_epi16(x_128[i],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
// temp = m0;
// tempd = &temp;
// printf("m0 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
// temp = m0;
// tempd = (int *)&temp;
// printf("m0 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
m1=m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[i] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e
// print_shorts(y_128[0],"y_128[0]=");
y_128[i] = _mm_shufflelo_epi16(y_128[i],0x1e);
y_128[i] = _mm_shufflehi_epi16(y_128[i],0x1e);
((int16_t*)&y_128[i])[1] = -((int16_t*)&y_128[i])[1];
((int16_t*)&y_128[i])[5] = -((int16_t*)&y_128[i])[5];
// print_shorts(y_128[0],"y_128[0]=");
}
}
@@ -415,12 +316,13 @@ int rotate_cpx_vector2(int16_t *x,
return(0);
}
*/
int rotate_cpx_vector_norep(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift)
int rotate_cpx_vector(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift)
{
// Multiply elementwise two complex vectors of N elements
// x - input 1 in the format |Re0 Im0 |,......,|Re(N-1) Im(N-1)|
@@ -438,20 +340,13 @@ int rotate_cpx_vector_norep(int16_t *x,
uint32_t i; // loop counter
register __m128i m0,m1,m2,m3;
// int16_t *temps;
// int *tempd;
simd_q15_t *y_128,alpha_128;
int32_t *xd=(int32_t *)x;
int *xd;
//__m128i *x_128;
__m128i *y_128;
// __m128i temp;
shift = _mm_cvtsi32_si128(output_shift);
xd = (int *) x;
y_128 = (__m128i *) y;
#if defined(__x86_64__) || defined(__i386__)
__m128i shift = _mm_cvtsi32_si128(output_shift);
register simd_q15_t m0,m1,m2,m3;
((int16_t *)&alpha_128)[0] = alpha[0];
((int16_t *)&alpha_128)[1] = -alpha[1];
@@ -461,43 +356,55 @@ int rotate_cpx_vector_norep(int16_t *x,
((int16_t *)&alpha_128)[5] = -alpha[1];
((int16_t *)&alpha_128)[6] = alpha[1];
((int16_t *)&alpha_128)[7] = alpha[0];
#elif defined(__arm__)
int32x4_t shift;
int32x4_t ab_re0,ab_re1,ab_im0,ab_im1,re32,im32;
int16_t reflip[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
int32x4x2_t xtmp;
((int16_t *)&alpha_128)[0] = alpha[0];
((int16_t *)&alpha_128)[1] = alpha[1];
((int16_t *)&alpha_128)[2] = alpha[0];
((int16_t *)&alpha_128)[3] = alpha[1];
((int16_t *)&alpha_128)[4] = alpha[0];
((int16_t *)&alpha_128)[5] = alpha[1];
((int16_t *)&alpha_128)[6] = alpha[0];
((int16_t *)&alpha_128)[7] = alpha[1];
int16x8_t bflip = vrev32q_s16(alpha_128);
int16x8_t bconj = vmulq_s16(alpha_128,*(int16x8_t *)reflip);
shift = vdupq_n_s32(-output_shift);
#endif
y_128 = (simd_q15_t *) y;
// _mm_empty();
// return(0);
for(i=0; i<N>>2; i++) {
#if defined(__x86_64__) || defined(__i386__)
m0 = _mm_setr_epi32(xd[0],xd[0],xd[1],xd[1]);
m1 = _mm_setr_epi32(xd[2],xd[2],xd[3],xd[3]);
// printf("i=%d\n",i);
// temps = (short *)x1_128;
// printf("x1 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
// temps = (short *)x2_128;
// printf("x2 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
m2 = _mm_madd_epi16(m0,alpha_128); //complex multiply. result is 32bit [Re Im Re Im]
m3 = _mm_madd_epi16(m1,alpha_128); //complex multiply. result is 32bit [Re Im Re Im]
// temp = m0;
// tempd = &temp;
// printf("m0 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
m2 = _mm_sra_epi32(m2,shift); // shift right by shift in order to compensate for the input amplitude
m3 = _mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude
// temp = m0;
// tempd = (int *)&temp;
// printf("m0 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
y_128[0] = _mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im]
#elif defined(__arm__)
// temps = (short *)&y_128[0];
// printf("y0 : %d,%d,%d,%d,%d,%d,%d,%d\n",temps[0],temps[1],temps[2],temps[3],temps[4],temps[5],temps[6],temps[7]);
ab_re0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bconj)[0]);
ab_re1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bconj)[1]);
ab_im0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bflip)[0]);
ab_im1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bflip)[1]);
re32 = vshlq_s32(vcombine_s32(vpadd_s32(((int32x2_t*)&ab_re0)[0],((int32x2_t*)&ab_re0)[1]),
vpadd_s32(((int32x2_t*)&ab_re1)[0],((int32x2_t*)&ab_re1)[1])),
shift);
im32 = vshlq_s32(vcombine_s32(vpadd_s32(((int32x2_t*)&ab_im0)[0],((int32x2_t*)&ab_im0)[1]),
vpadd_s32(((int32x2_t*)&ab_im1)[0],((int32x2_t*)&ab_im1)[1])),
shift);
xtmp = vzipq_s32(re32,im32);
y_128[0] = vcombine_s16(vmovn_s32(xtmp.val[0]),vmovn_s32(xtmp.val[1]));
#endif
xd+=4;
y_128+=1;
@@ -510,7 +417,7 @@ int rotate_cpx_vector_norep(int16_t *x,
return(0);
}
/*
int mult_vector32_scalar(int16_t *x1,
int x2,
int16_t *y,
@@ -530,16 +437,6 @@ int mult_vector32_scalar(int16_t *x1,
uint32_t i; // loop counter
/*
#ifdef USER_MODE
char *tempc;
short *temps;
int *tempd;
long long *templ;
__m128i temp;
#endif
*/
__m128i *x1_128;
__m128i x2_128;
__m128i *y_128;
@@ -553,20 +450,6 @@ int mult_vector32_scalar(int16_t *x1,
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>3); i++) {
y_128[0] = _mm_mul_epu32(x1_128[0],x2_128);
/*
#ifdef USER_MODE
printf("i=%d\n",i);
tempd = (int *)x1_128;
printf("x1 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
tempd = (int *)&x2_128;
printf("x2 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
// tempd = (int *)y_128;
// printf("y : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
templ = (long long *)y_128;
printf("y : %lld,%lld\n",templ[0],templ[1]);
#endif
*/
y_128[1] = _mm_mul_epu32(x1_128[1],x2_128);
y_128[2] = _mm_mul_epu32(x1_128[2],x2_128);
y_128[3] = _mm_mul_epu32(x1_128[3],x2_128);
@@ -582,7 +465,7 @@ int mult_vector32_scalar(int16_t *x1,
return(0);
}
*/
int complex_conjugate(int16_t *x1,
int16_t *y,
@@ -591,46 +474,20 @@ int complex_conjugate(int16_t *x1,
{
uint32_t i; // loop counter
/*
#ifdef USER_MODE
char *tempc;
short *temps;
int *tempd;
long long *templ;
__m128i temp;
#endif
*/
__m128i *x1_128;
__m128i x2_128;
__m128i *y_128;
x1_128 = (__m128i *)&x1[0];
x2_128 = _mm_set_epi16(-1,1,-1,1,-1,1,-1,1);
y_128 = (__m128i *)&y[0];
simd_q15_t *x1_128;
simd_q15_t *y_128;
int16_t x2[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
simd_q15_t *x2_128 = (simd_q15_t*)&x2[0];
x1_128 = (simd_q15_t *)&x1[0];
y_128 = (simd_q15_t *)&y[0];
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>3); i++) {
y_128[0] = _mm_mullo_epi16(x1_128[0],x2_128);
/*
#ifdef USER_MODE
printf("i=%d\n",i);
tempd = (int *)x1_128;
printf("x1 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
tempd = (int *)&x2_128;
printf("x2 : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
// tempd = (int *)y_128;
// printf("y : %d,%d,%d,%d\n",tempd[0],tempd[1],tempd[2],tempd[3]);
templ = (long long *)y_128;
printf("y : %lld,%lld\n",templ[0],templ[1]);
#endif
*/
y_128[1] = _mm_mullo_epi16(x1_128[1],x2_128);
y_128[2] = _mm_mullo_epi16(x1_128[2],x2_128);
y_128[3] = _mm_mullo_epi16(x1_128[3],x2_128);
y_128[0] = mullo_int16(x1_128[0],*x2_128);
y_128[1] = mullo_int16(x1_128[1],*x2_128);
y_128[2] = mullo_int16(x1_128[2],*x2_128);
y_128[3] = mullo_int16(x1_128[3],*x2_128);
x1_128+=4;
@@ -706,15 +563,3 @@ main ()
#endif //MAIN
#else //EXPRESSMIMO_TARGET
int rotate_cpx_vector(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift,
uint8_t format)
{
}
#endif //EXPRESSMIMO_TARGET
File diff suppressed because it is too large Load Diff
-13
View File
@@ -28,7 +28,6 @@
*******************************************************************************/
#include "defs.h"
#ifndef EXPRESSMIMO_TARGET
static __m128i shift __attribute__ ((aligned(16)));
@@ -365,15 +364,3 @@ main ()
}
#endif //MAIN
#else //EXPRESSMIMO_TARGET
int mult_cpx_vector_h(short *x1,
short *x2,
short *y,
unsigned int N,
unsigned short output_shift,
short sign)
{
}
#endif //EXPRESSMIMO_TARGET
+8 -58
View File
@@ -64,7 +64,6 @@ struct complex32 {
int32_t i;
};
#ifndef EXPRESSMIMO_TARGET
/*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
This function performs componentwise multiplication and accumulation of a complex scalar and a real vector.
@param x Vector input (Q1.15)
@@ -339,42 +338,7 @@ void dft3072(int16_t *sigF,int16_t *sig);
void dft24576(int16_t *sigF,int16_t *sig);
/*!\fn int rotate_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift, uint8_t format)
This function performs componentwise multiplication of a vector with a complex scalar.
@param x Vector input (Q1.15) in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
@param alpha Scalar input (Q1.15) in the format |Re0 Im0|
@param y Output (Q1.15) in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
@param N Length of x WARNING: N>=4
@param output_shift Number of bits to shift output down to Q1.15 (should be 15 for Q1.15 inputs) WARNING: log2_amp>0 can cause overflow!!
@param format Format 0 indicates that alpha is in shuffled format during multiply (Re -Im Im Re), whereas 1 indicates that input is in this format (i.e. a matched filter)
The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$
*/
int32_t rotate_cpx_vector(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift,
uint8_t format);
/*!\fn int32_t rotate_cpx_vector2(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift,uint8_t format)
This function performs componentwise multiplication of a vector with a complex scalar.
@param x Vector input (Q1.15) in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
@param alpha Scalar input (Q1.15) in the format |Re0 Im0|
@param y Output (Q1.15) in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
@param N Length of x WARNING: N must be multiple of 2 (the routine performs two complex multiplies per cycle)
@param output_shift Number of bits to shift output down to Q1.15 (should be 15 for Q1.15 inputs) WARNING: log2_amp>0 can cause overflow!!
@param format Format 0 indicates that alpha is in shuffled format during multiply (Re -Im Im Re), whereas 1 indicates that input is in this format (i.e. a matched filter)
The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$
*/
int32_t rotate_cpx_vector2(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift,
uint8_t format);
/*!\fn int32_t rotate_cpx_vector_norep(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift)
/*!\fn int32_t rotate_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift)
This function performs componentwise multiplication of a vector with a complex scalar.
@param x Vector input (Q1.15) in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)|
@param alpha Scalar input (Q1.15) in the format |Re0 Im0|
@@ -384,19 +348,19 @@ This function performs componentwise multiplication of a vector with a complex s
The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$
*/
int32_t rotate_cpx_vector_norep(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift);
int32_t rotate_cpx_vector(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift);
/*!\fn int32_t add_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
This function performs componentwise addition of a vector with a complex scalar.
@param x Vector input (Q1.15) in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
@param x Vector input (Q1.15) in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
@param alpha Scalar input (Q1.15) in the format |Re0 Im0|
@param y Output (Q1.15) in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
@param y Output (Q1.15) in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
@param N Length of x WARNING: N>=4
The function implemented is : \f$\mathbf{y} = \alpha + \mathbf{x}\f$
@@ -515,20 +479,6 @@ Compensate the phase rotation of the RF. WARNING: This function is currently unu
*/
#else // EXPRESSMIMO_TARGET
#define fft(x,y,twiddle,rev,log2size,scale,input_fmt) \
(((twiddle)==0) ? \
(fft(1<<(log2size),((unsigned long*)(x)),((unsigned long*)(y)))) : \
(ifft(1<<(log2size),((unsigned long*)(x)),((unsigned long*)(y)))))
#define mult_cpx_vector(x1,x2,y,N,os) component_wise_product(N,(unsigned long *)(x1),(unsigned long *)(x2),(unsigned long *)(y))
#define mult_cpx_vector2(x1,x2,y,N,os) component_wise_product(N,(unsigned long *)(x1),(unsigned long *)(x2),(unsigned long *)(y))
#define add_vector16(x,y,z,N) component_wise_addition(N,(unsigned long*)(x),(unsigned long*)(y),(unsigned long*)(z))
#endif // EXPRESSMIMO_TARGET
int8_t dB_fixed(uint32_t x);
+1599 -1096
View File
File diff suppressed because it is too large Load Diff
+53 -15
View File
@@ -77,10 +77,10 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui );
// Define form
fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 600 );
fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 800 );
// This the whole UI box
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 600, "" );
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
// Received signal
@@ -118,6 +118,22 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
fl_set_xyplot_symbolsize( fdui->pusch_comp,2);
fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
// I/Q PUCCH comp (format 1)
fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pucch_comp1, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pucch_comp1,2);
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
// I/Q PUCCH comp (fromat 1a/b)
fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pucch_comp, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pucch_comp,2);
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
// Throughput on PUSCH
fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" );
fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX );
@@ -125,7 +141,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color
// Generic eNB Button
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 480, 240, 40, "" );
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
fl_set_button(fdui->button_0,0);
otg_enabled = 0;
@@ -154,9 +170,12 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
int16_t **chest_f;
int16_t *pusch_llr;
int16_t *pusch_comp;
int32_t *pucch1_comp;
int16_t *pucch1ab_comp;
float Re,Im,ymax;
float *llr, *bit;
float I[nsymb_ce*2], Q[nsymb_ce*2];
float I_pucch[10240],Q_pucch[10240],A_pucch[10240],B_pucch[10240];
float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
float chest_t_abs[nb_antennas_rx][frame_parms->ofdm_symbol_size];
float *chest_f_abs;
@@ -186,6 +205,8 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
chest_f = (int16_t**) phy_vars_enb->lte_eNB_pusch_vars[UE_id]->drs_ch_estimates[eNB_id];
pusch_llr = (int16_t*) phy_vars_enb->lte_eNB_pusch_vars[UE_id]->llr;
pusch_comp = (int16_t*) phy_vars_enb->lte_eNB_pusch_vars[UE_id]->rxdataF_comp[eNB_id][0];
pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id];
pucch1ab_comp = (int16_t*) phy_vars_enb->pucch1ab_stats[UE_id];
// Received signal in time domain of receive antenna 0
if (rxsig_t != NULL) {
@@ -209,13 +230,13 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
}
}
// Channel Impulse Response
// Channel Impulse Response
if (chest_t != NULL) {
ymax = 0;
if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
chest_t_abs[0][i] = (float) (chest_t[0][2*i]*chest_t[0][2*i]+chest_t[0][2*i+1]*chest_t[0][2*i+1]);
chest_t_abs[0][i] = 10*log10((float) (chest_t[0][2*i]*chest_t[0][2*i]+chest_t[0][2*i+1]*chest_t[0][2*i+1]));
if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i];
@@ -227,8 +248,8 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
for (arx=1; arx<nb_antennas_rx; arx++) {
if (chest_t[arx] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
chest_t_abs[arx][i] = (float) (chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]);
chest_t_abs[arx][i] = 10*log10((float) (chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
if (chest_t_abs[arx][i] > ymax)
ymax = chest_t_abs[arx][i];
}
@@ -313,6 +334,22 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
}
// PUSCH I/Q of MF Output
if (pucch1ab_comp!=NULL) {
for (ind=0; ind<10240; ind++) {
I_pucch[ind] = pucch1ab_comp[2*ind];
Q_pucch[ind] = pucch1ab_comp[2*ind+1];
A_pucch[ind] = 10*log10(pucch1_comp[ind]);
B_pucch[ind] = ind;
}
fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
fl_set_xyplot_xbounds(form->pucch_comp,-200,200);
fl_set_xyplot_ybounds(form->pucch_comp,-100,100);
fl_set_xyplot_ybounds(form->pucch_comp1,10,40);
}
// PUSCH Throughput
memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
@@ -380,8 +417,8 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
// fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
// fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
// LLR of PDCCH
fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
@@ -443,7 +480,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
{
int i,arx,atx,ind,k;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx_eNB;
int16_t **rxsig_t;
@@ -470,6 +507,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
unsigned char harq_pid = 0;
int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
if (phy_vars_ue->dlsch_ue[eNB_id][0]!=NULL) {
harq_pid = phy_vars_ue->dlsch_ue[eNB_id][0]->current_harq_pid;
@@ -493,7 +531,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
if (phy_vars_ue->dlsch_ue[eNB_id][0]!=NULL) {
coded_bits_per_codeword = get_G(frame_parms,
phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->nb_rb,
phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc,
phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
get_Qm(mcs),
phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl,
num_pdcch_symbols,
@@ -504,8 +542,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
}
I = (float*) calloc(nsymb_ce*2,sizeof(float));
Q = (float*) calloc(nsymb_ce*2,sizeof(float));
I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float));
Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float));
chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
for (arx=0; arx<nb_antennas_rx; arx++) {
@@ -699,8 +737,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
}
// PDSCH Throughput
memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
memmove( tput_ue[UE_id], &tput_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame;
tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+2
View File
@@ -46,6 +46,8 @@ typedef struct {
FL_OBJECT * chest_f;
FL_OBJECT * chest_t;
FL_OBJECT * pusch_comp;
FL_OBJECT * pucch_comp;
FL_OBJECT * pucch_comp1;
FL_OBJECT * pusch_llr;
FL_OBJECT * pusch_tput;
FL_OBJECT * button_0;
-7
View File
@@ -26,7 +26,6 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#ifndef EXPRESSMIMO_TARGET
#include "PHY/sse_intrin.h"
void Zero_Buffer(void *buf,unsigned int length)
@@ -63,12 +62,6 @@ void mmxcopy(void *dest,void *src,int size)
_mm_empty();
}
#else //EXPRESSMIMO_TARGET
#endif //EXPRESSMIMO_TARGET
void Zero_Buffer_nommx(void *buf,unsigned int length)
{
+84 -50
View File
@@ -28,19 +28,16 @@
*******************************************************************************/
#include "defs.h"
#ifndef EXPRESSMIMO_TARGET
#include "PHY/sse_intrin.h"
#endif //EXPRESSMIMO_TARGET
// Compute Energy of a complex signal vector, removing the DC component!
// input : points to vector
// length : length of vector in complex samples
#define shift 4
#define shift_DC 0
//#define shift_DC 0
#ifndef EXPRESSMIMO_TARGET
#if defined(__x86_64__) || defined(__i386__)
#ifdef LOCALIZATION
int32_t subcarrier_energy(int32_t *input,uint32_t length, int32_t *subcarrier_energy, uint16_t rx_power_correction)
{
@@ -70,9 +67,13 @@ int32_t subcarrier_energy(int32_t *input,uint32_t length, int32_t *subcarrier_en
subcarrier_energy[i] = subcarrier_pwr*rx_power_correction;
}
_mm_empty();
_m_empty();
return i;
}
#endif
int32_t signal_energy(int32_t *input,uint32_t length)
{
@@ -81,9 +82,6 @@ int32_t signal_energy(int32_t *input,uint32_t length)
register __m64 mm0,mm1,mm2,mm3;
__m64 *in = (__m64 *)input;
#ifdef MAIN
int16_t *printb;
#endif
mm0 = _mm_setzero_si64();//pxor(mm0,mm0);
mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
@@ -95,35 +93,14 @@ int32_t signal_energy(int32_t *input,uint32_t length)
mm1 = _m_pmaddwd(mm1,mm1);
mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes
// temp2 = mm0;
// printf("%d %d\n",((int *)&temp2)[0],((int *)&temp2)[1]);
// printb = (int16_t *)&mm2;
// printf("mm2 %d : %d %d %d %d\n",i,printb[0],printb[1],printb[2],printb[3]);
mm2 = _m_psrawi(mm2,shift_DC);
// mm2 = _m_psrawi(mm2,shift_DC);
mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes
// printb = (int16_t *)&mm3;
// printf("mm3 %d : %d %d %d %d\n",i,printb[0],printb[1],printb[2],printb[3]);
}
/*
#ifdef MAIN
printb = (int16_t *)&mm3;
printf("%d %d %d %d\n",printb[0],printb[1],printb[2],printb[3]);
#endif
*/
mm1 = mm0;
mm0 = _m_psrlqi(mm0,32);
mm0 = _m_paddd(mm0,mm1);
temp = _m_to_int(mm0);
temp/=length;
temp<<=shift; // this is the average of x^2
@@ -132,26 +109,15 @@ int32_t signal_energy(int32_t *input,uint32_t length)
mm2 = _m_psrlqi(mm3,32);
mm2 = _m_paddw(mm2,mm3);
mm2 = _m_pmaddwd(mm2,mm2);
temp2 = _m_to_int(mm2);
temp2/=(length*length);
temp2<<=(2*shift_DC);
#ifdef MAIN
printf("E x^2 = %d\n",temp);
#endif
// temp2<<=(2*shift_DC);
temp -= temp2;
#ifdef MAIN
printf("(E x)^2=%d\n",temp2);
#endif
_mm_empty();
_m_empty();
return((temp>0)?temp:1);
}
@@ -214,6 +180,81 @@ int32_t signal_energy_nodc(int32_t *input,uint32_t length)
return((temp>0)?temp:1);
}
#elif defined(__arm__)
int32_t signal_energy(int32_t *input,uint32_t length)
{
int32_t i;
int32_t temp,temp2;
register int32x4_t tmpE,tmpDC;
int32x2_t tmpE2,tmpDC2;
int16x4_t *in = (int16x4_t *)input;
tmpE = vdupq_n_s32(0);
tmpDC = vdupq_n_s32(0);
for (i=0; i<length>>1; i++) {
tmpE = vqaddq_s32(tmpE,vshrq_n_s32(vmull_s16(*in,*in),shift));
tmpDC = vaddw_s16(tmpDC,vshr_n_s16(*in++,shift_DC));
}
tmpE2 = vpadd_s32(vget_low_s32(tmpE),vget_high_s32(tmpE));
temp=(vget_lane_s32(tmpE2,0)+vget_lane_s32(tmpE2,1))/length;
temp<<=shift; // this is the average of x^2
// now remove the DC component
tmpDC2 = vpadd_s32(vget_low_s32(tmpDC),vget_high_s32(tmpDC));
temp2=(vget_lane_s32(tmpDC2,0)+vget_lane_s32(tmpDC2,1))/(length*length);
// temp2<<=(2*shift_DC);
#ifdef MAIN
printf("E x^2 = %d\n",temp);
#endif
temp -= temp2;
#ifdef MAIN
printf("(E x)^2=%d\n",temp2);
#endif
return((temp>0)?temp:1);
}
int32_t signal_energy_nodc(int32_t *input,uint32_t length)
{
int32_t i;
int32_t temp;
register int32x4_t tmpE;
int32x2_t tmpE2;
int16x4_t *in = (int16x4_t *)input;
tmpE = vdupq_n_s32(0);
for (i=0; i<length>>1; i++) {
tmpE = vqaddq_s32(tmpE,vshrq_n_s32(vmull_s16(*in,*in),shift));
}
tmpE2 = vpadd_s32(vget_low_s32(tmpE),vget_high_s32(tmpE));
temp=(vget_lane_s32(tmpE2,0)+vget_lane_s32(tmpE2,1))/length;
temp<<=shift; // this is the average of x^2
#ifdef MAIN
printf("E x^2 = %d\n",temp);
#endif
return((temp>0)?temp:1);
}
#endif
double signal_energy_fp(double **s_re,double **s_im,uint32_t nb_antennas,uint32_t length,uint32_t offset)
{
@@ -243,13 +284,6 @@ double signal_energy_fp2(struct complex *s,uint32_t length)
return(V/length);
}
#else
int32_t signal_energy(int32_t *input,uint32_t length)
{
}
#endif
#ifdef MAIN
#define LENGTH 256
+4 -11
View File
@@ -33,25 +33,18 @@
// global var for openair performance profiler
int opp_enabled = 0;
/*
double get_cpu_freq_GHz(void) {
time_stats_t ts;
reset_meas(&ts);
start_meas(&ts);
sleep(1);
stop_meas(&ts);
return (double)ts.diff/1000000000;
}*/
double get_cpu_freq_GHz(void) {
time_stats_t ts = {0};
reset_meas(&ts);
start_meas(&ts);
ts.trials++;
ts.in = rdtsc_oai();
sleep(1);
stop_meas(&ts);
ts.diff = (rdtsc_oai()-ts.in);
cpu_freq_GHz = (double)ts.diff/1000000000;
printf("CPU Freq is %f \n", cpu_freq_GHz);
return cpu_freq_GHz;
}
+42 -61
View File
@@ -26,27 +26,42 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#ifdef OMP
#include <omp.h>
#endif
#include <unistd.h>
#include <math.h>
#include <stdint.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <linux/kernel.h>
#include <linux/types.h>
// global var to enable openair performance profiler
extern int opp_enabled;
double cpu_freq_GHz;
#if defined(__x86_64__) || defined(__i386__)
typedef struct {
long long in;
long long diff_now;
long long diff;
long long diff_now;
long long p_time; /*!< \brief absolute process duration */
long long diff_square; /*!< \brief process duration square */
long long max;
int trials;
} time_stats_t;
#elif defined(__arm__)
typedef struct {
uint32_t in;
uint32_t diff_now;
uint32_t diff;
uint32_t p_time; /*!< \brief absolute process duration */
uint32_t diff_square; /*!< \brief process duration square */
uint32_t max;
int trials;
} time_stats_t;
#endif
static inline void start_meas(time_stats_t *ts) __attribute__((always_inline));
static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
@@ -74,12 +89,12 @@ static inline unsigned long long rdtsc_oai(void)
}
#elif defined(__arm__)
static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline));
static inline unsigned long long rdtsc_oai(void)
static inline uint32_t rdtsc_oai(void) __attribute__((always_inline));
static inline uint32_t rdtsc_oai(void)
{
uint32_t r = 0;
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(r) );
return (unsigned long long)r;
return r;
}
#endif
@@ -88,17 +103,8 @@ static inline void start_meas(time_stats_t *ts)
if (opp_enabled) {
#ifdef OMP
int tid;
tid = omp_get_thread_num();
if (tid==0)
#endif
{
ts->trials++;
ts->in = rdtsc_oai();
}
}
}
@@ -107,46 +113,29 @@ static inline void stop_meas(time_stats_t *ts)
if (opp_enabled) {
long long out = rdtsc_oai();
#ifdef OMP
int tid;
tid = omp_get_thread_num();
if (tid==0)
#endif
{
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in);
/// process duration is the difference between two clock points
ts->p_time = (out-ts->in);
ts->diff_square += pow((out-ts->in),2);
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;
}
ts->diff_now = (out-ts->in);
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in);
/// process duration is the difference between two clock points
ts->p_time = (out-ts->in);
ts->diff_square += (out-ts->in)*(out-ts->in);
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;
}
}
static inline void reset_meas(time_stats_t *ts)
{
static int cpu_freq_set=0;
if (opp_enabled) {
ts->trials=0;
ts->diff_now=0;
ts->diff=0;
ts->p_time=0;
ts->diff_square=0;
ts->max=0;
static inline void reset_meas(time_stats_t *ts) {
if (cpu_freq_set == 0) {
cpu_freq_set = 1;
get_cpu_freq_GHz();
printf("CPU Freq is %f \n", cpu_freq_GHz);
}
}
ts->trials=0;
ts->diff=0;
ts->diff_now=0;
ts->p_time=0;
ts->diff_square=0;
ts->max=0;
}
@@ -159,11 +148,3 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts)
dst_ts->max=src_ts->max;
}
}
/*static inline double get_mean_meas_us(time_stats_t *ts, double cpu_freq_GHz) {
return (double) ts->diff/ts->trials/cpu_freq_GHz/1000.0;
}
*/
+1 -1
View File
@@ -25,4 +25,4 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
*******************************************************************************/
+21 -26
View File
@@ -51,7 +51,7 @@
# define msg mexPrintf
#else
# ifdef OPENAIR2
# if defined(ENABLE_RAL)
# if ENABLE_RAL
# include "collection/hashtable/hashtable.h"
# include "COMMON/ral_messages_types.h"
# include "UTIL/queue.h"
@@ -65,38 +65,31 @@
//use msg in the real-time thread context
#define msg_nrt printf
//use msg_nrt in the non real-time context (for initialization, ...)
#ifdef EXPRESSMIMO_TARGET
#define malloc16(x) malloc(x)
#else //EXPRESSMIMO_TARGET
#ifdef __AVX2__
#define malloc16(x) memalign(32,x)
#else
#define malloc16(x) memalign(16,x)
#endif //EXPRESSMIMO_TARGET
#endif
#define free16(y,x) free(y)
#define bigmalloc malloc
#define bigmalloc16 malloc16
#define openair_free(y,x) free((y))
#define PAGE_SIZE 4096
#ifdef EXPRESSMIMO_TARGET
//! \brief Allocate \c size bytes of memory on the heap and zero it afterwards.
//! If no more memory is available, this function will terminate the program with an assertion error.
static inline void* malloc16_clear( size_t size )
{
void* ptr = malloc(size);
DevAssert(ptr);
memset( ptr, 0, size );
return ptr;
}
#else //EXPRESSMIMO_TARGET
//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards.
//! If no more memory is available, this function will terminate the program with an assertion error.
static inline void* malloc16_clear( size_t size )
{
#ifdef __AVX2__
void* ptr = memalign(32, size);
#else
void* ptr = memalign(16, size);
#endif
DevAssert(ptr);
memset( ptr, 0, size );
return ptr;
}
#endif //EXPRESSMIMO_TARGET
#define PAGE_MASK 0xfffff000
@@ -119,10 +112,6 @@ static inline void* malloc16_clear( size_t size )
/// suppress compiler warning for unused arguments
#define UNUSED(x) (void)x;
#ifdef EXPRESSMIMO_TARGET
#define Zero_Buffer(x,y) Zero_Buffer_nommx(x,y)
#endif //EXPRESSMiMO_TARGET
#include "spec_defs_top.h"
#include "impl_defs_top.h"
@@ -146,7 +135,7 @@ static inline void* malloc16_clear( size_t size )
#define NB_BANDS_MAX 8
typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5} runmode_t;
typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t;
enum transmission_access_mode {
NO_ACCESS=0,
@@ -164,7 +153,7 @@ typedef struct UE_SCAN_INFO_s {
int32_t freq_offset_Hz[3][10];
} UE_SCAN_INFO_t;
#if defined(ENABLE_RAL)
#if ENABLE_RAL
typedef struct ral_threshold_phy_s {
SLIST_ENTRY(ral_threshold_phy_s) ral_thresholds;
ral_threshold_t threshold;
@@ -391,7 +380,12 @@ typedef struct PHY_VARS_eNB_s {
time_stats_t localization_stats;
#endif
#if defined(ENABLE_RAL)
int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10];
int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024];
int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX][10];
int32_t pucch1ab_stats[NUMBER_OF_UE_MAX][10*1024];
#if ENABLE_RAL
hash_table_t *ral_thresholds_timed;
SLIST_HEAD(ral_thresholds_gen_poll_enb_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_enb_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
@@ -419,6 +413,8 @@ typedef struct {
runmode_t mode;
/// \brief Indicator that UE should perform band scanning
int UE_scan;
/// \brief Indicator that UE should perform coarse scanning around carrier
int UE_scan_carrier;
/// \brief Indicator that UE is synchronized to an eNB
int is_synchronized;
/// \brief Instance count of TX processing thread (-1 means ready, 0 means busy)
@@ -505,7 +501,6 @@ typedef struct {
uint8_t pucch_payload[22];
UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
int8_t g_pucch[NUMBER_OF_CONNECTED_eNB_MAX];
/// cell-specific reference symbols
uint32_t lte_gold_table[7][20][2][14];
@@ -669,7 +664,7 @@ typedef struct {
time_stats_t dlsch_tc_intl2_stats;
time_stats_t tx_prach;
#if defined(ENABLE_RAL)
#if ENABLE_RAL
hash_table_t *ral_thresholds_timed;
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
+2
View File
@@ -68,6 +68,8 @@ typedef enum {TDD=1,FDD=0} lte_frame_type_t;
typedef enum {EXTENDED=1,NORMAL=0} lte_prefix_type_t;
typedef enum {LOCALIZED=0,DISTRIBUTED=1} vrb_t;
/// Enumeration for parameter PHICH-Duration \ref PHICH_CONFIG_COMMON::phich_duration.
typedef enum {
normal=0,
+25 -8
View File
@@ -43,9 +43,21 @@
/** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation
* @{
* @defgroup _physical_layer_ref_implementation_ Physical Layer Reference Implementation
* @defgroup _PHY_RF_INTERFACE_ Generic PHY - RF Interface
* @ingroup _ref_implementation_
* @{
* This module is responsible for defining the generic interface between PHY and RF Target
* @}
* @defgroup _openair1_ openair1 Reference Implementation
* @ingroup _ref_implementation_
* @{
* @defgroup _physical_layer_ref_implementation_ Physical Layer Reference Implementation
* @ingroup _openair1_
* @{
* @defgroup _PHY_STRUCTURES_ Basic Structures and Memory Initialization
@@ -83,14 +95,16 @@
* @{
* This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels.
* @}
* @}
* @defgroup _PHY_PROCEDURES_ Physical Layer Procedures
* @ingroup _ref_implementation_
* @ingroup _physical_layer_ref_implementation_
* @{
* This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels.
* @}
* @}
* @}
* @}
*/
#include "types.h"
@@ -98,7 +112,7 @@
/**@addtogroup _PHY_STRUCTURES_
/** @addtogroup _PHY_STRUCTURES_
* @{
*/
#define NUMBER_OF_OFDM_CARRIERS (frame_parms->ofdm_symbol_size)
@@ -242,6 +256,10 @@
#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
/// Threshold for PUCCH Format 1 detection
#define PUCCH1_THRES 10
/// Threshold for PUCCH Format 1a/1b detection
#define PUCCH1a_THRES 4
#ifndef OPENAIR_LTE
///
@@ -322,10 +340,10 @@ typedef struct {
#define NUMBER_OF_SUBBANDS_MAX 13
#define NUMBER_OF_HARQ_PID_MAX 8
#if defined(CBMIMO1) || defined(EXMIMO)
#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP)
#define MAX_FRAME_NUMBER 0x400
#define NUMBER_OF_eNB_MAX 1
#define NUMBER_OF_UE_MAX 16
#define NUMBER_OF_UE_MAX 4
#define NUMBER_OF_CONNECTED_eNB_MAX 3
#else
#define MAX_FRAME_NUMBER 0xFFFF
@@ -493,6 +511,5 @@ typedef struct {
#define MCS_TABLE_LENGTH_MAX 64
#endif //__PHY_IMPLEMENTATION_DEFS_H__
/**@}
*@}
/**@}
*/
+3
View File
@@ -63,6 +63,9 @@
# include <smmintrin.h>
#endif
#ifdef __AVX2__
# include <immintrin.h>
#endif
// ------------------------------------------------
// compatibility functions if SSE3 or SSE4 is not available
+44 -67
View File
@@ -114,7 +114,7 @@ typedef struct {
int32_t freq_offset;
uint32_t tx_rx_switch_point;
uint32_t manual_timing_advance; /// 1 to override automatic timing advance
uint32_t timing_advance;
int32_t timing_advance;
uint32_t dual_tx; /// 1 for dual-antenna TX, 0 for single-antenna TX
uint32_t tdd; /// 1 for TDD mode, 0 for FDD mode
uint32_t rx_rf_mode;
@@ -149,8 +149,8 @@ void cleanup_dlsch_threads(void);
*/
/*!
\brief Top-level entry routine for eNB procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe.
/*! \brief Top-level entry routine for eNB procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe.
@param subframe Index of current subframe (0-9)
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -158,8 +158,8 @@ void cleanup_dlsch_threads(void);
@param *phy_vars_rn pointer to RN variables
*/
void phy_procedures_eNB_lte(uint8_t subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t abstraction_flag, relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn);
/*!
\brief Top-level entry routine for UE procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe.
/*! \brief Top-level entry routine for UE procedures. Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required). On odd slots, it generate TX waveform for the following subframe.
@param last_slot Index of last slot (0-19)
@param next_slot Index of next_slot (0-19)
@param phy_vars_ue Pointer to UE variables on which to act
@@ -172,15 +172,13 @@ void phy_procedures_eNB_lte(uint8_t subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t
void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
#ifdef Rel10
/*!
\brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs.
/*! \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs.
@param last_slot Index of last slot (0-19)
@param next_slot Index of next_slot (0-19)
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type);
/*!
\brief Top-level entry routine for relay node procedures actinf as UE. This proc will make us of the existing UE procs.
/*! \brief Top-level entry routine for relay node procedures actinf as UE. This proc will make us of the existing UE procs.
@param last_slot Index of last slot (0-19)
@param next_slot Index of next_slot (0-19)
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
@@ -188,8 +186,7 @@ int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, r
int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type);
#endif
/*!
\brief Scheduling for UE TX procedures in normal subframes.
/*! \brief Scheduling for UE TX procedures in normal subframes.
@param phy_vars_ue Pointer to UE variables on which to act
@param eNB_id Local id of eNB on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -197,8 +194,7 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
/*!
\brief Scheduling for UE RX procedures in normal subframes.
/*! \brief Scheduling for UE RX procedures in normal subframes.
@param last_slot Index of last slot (0-19)
@param phy_vars_ue Pointer to UE variables on which to act
@param eNB_id Local id of eNB on which to act
@@ -209,8 +205,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstra
*/
int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
/*!
\brief Scheduling for UE TX procedures in TDD S-subframes.
/*! \brief Scheduling for UE TX procedures in TDD S-subframes.
@param phy_vars_ue Pointer to UE variables on which to act
@param eNB_id Local id of eNB on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -218,8 +213,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstrac
*/
void phy_procedures_UE_S_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type);
/*!
\brief Scheduling for UE RX procedures in TDD S-subframes.
/*! \brief Scheduling for UE RX procedures in TDD S-subframes.
@param last_slot Index of last slot (0-19)
@param phy_vars_ue Pointer to UE variables on which to act
@param eNB_id Local id of eNB on which to act
@@ -228,8 +222,7 @@ void phy_procedures_UE_S_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abst
*/
void phy_procedures_UE_S_RX(uint8_t last_slot,PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag, relaying_type_t r_type);
/*!
\brief Scheduling for eNB TX procedures in normal subframes.
/*! \brief Scheduling for eNB TX procedures in normal subframes.
@param next_slot Index of next slot (0-19)
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -238,8 +231,7 @@ void phy_procedures_UE_S_RX(uint8_t last_slot,PHY_VARS_UE *phy_vars_ue,uint8_t e
*/
void phy_procedures_eNB_TX(uint8_t next_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
/*!
\brief Scheduling for eNB RX procedures in normal subframes.
/*! \brief Scheduling for eNB RX procedures in normal subframes.
@param last_slot Index of last slot (0-19)
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -247,8 +239,7 @@ void phy_procedures_eNB_TX(uint8_t next_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t
*/
void phy_procedures_eNB_RX(uint8_t last_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type);
/*!
\brief Scheduling for eNB TX procedures in TDD S-subframes.
/*! \brief Scheduling for eNB TX procedures in TDD S-subframes.
@param next_slot Index of next slot (0-19)
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -256,8 +247,7 @@ void phy_procedures_eNB_RX(uint8_t last_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t
*/
void phy_procedures_eNB_S_TX(uint8_t next_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type);
/*!
\brief Scheduling for eNB RX procedures in TDD S-subframes.
/*! \brief Scheduling for eNB RX procedures in TDD S-subframes.
@param last_slot Index of next slot (0-19)
@param phy_vars_eNB Pointer to eNB variables on which to act
@param abstraction_flag Indicator of PHY abstraction
@@ -265,16 +255,14 @@ void phy_procedures_eNB_S_TX(uint8_t next_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_
*/
void phy_procedures_eNB_S_RX(uint8_t last_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type);
/*!
\brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
@param frame_parms Pointer to DL frame parameter descriptor
@param subframe Subframe index
@returns Subframe type (DL,UL,S)
*/
lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
/*!
\brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index. Same as subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler.
/*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index. Same as subframe_select, except that it uses the Mod_id and is provided as a service to the MAC scheduler.
@param Mod_id Index of eNB
@param CC_id Component Carrier Index
@param subframe Subframe index
@@ -282,16 +270,14 @@ lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe)
*/
lte_subframe_t get_subframe_direction(uint8_t Mod_id, uint8_t CC_id,uint8_t subframe);
/*!
\brief Function to indicate PHICH transmission subframes. Implements Table 9.1.2-1 for TDD.
/*! \brief Function to indicate PHICH transmission subframes. Implements Table 9.1.2-1 for TDD.
@param frame_parms Pointer to DL frame parameter descriptor
@param subframe Subframe index
@returns 1 if PHICH can be transmitted in subframe (always 1 for FDD)
*/
uint32_t is_phich_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
/*!
\brief Function to compute timing of Msg3 transmission on UL-SCH (first UE transmission in RA procedure). This implements the timing in paragraph a) from Section 6.1.1 in 36.213 (p. 17 in version 8.6). Used by eNB upon transmission of random-access response (RA_RNTI) to program corresponding ULSCH reception procedure. Used by UE upon reception of random-access response (RA_RNTI) to program corresponding ULSCH transmission procedure. This does not support the UL_delay field in RAR (always assumed to be 0).
/*! \brief Function to compute timing of Msg3 transmission on UL-SCH (first UE transmission in RA procedure). This implements the timing in paragraph a) from Section 6.1.1 in 36.213 (p. 17 in version 8.6). Used by eNB upon transmission of random-access response (RA_RNTI) to program corresponding ULSCH reception procedure. Used by UE upon reception of random-access response (RA_RNTI) to program corresponding ULSCH transmission procedure. This does not support the UL_delay field in RAR (always assumed to be 0).
@param frame_parms Pointer to DL frame parameter descriptor
@param current_subframe Index of subframe where RA_RNTI was received
@param current_frame Index of frame where RA_RNTI was received
@@ -304,8 +290,7 @@ void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms,
uint32_t *frame,
uint8_t *subframe);
/*!
\brief Function to compute timing of Msg3 retransmission on UL-SCH (first UE transmission in RA procedure).
/*! \brief Function to compute timing of Msg3 retransmission on UL-SCH (first UE transmission in RA procedure).
@param frame_parms Pointer to DL frame parameter descriptor
@param current_subframe Index of subframe where RA_RNTI was received
@param current_frame Index of frame where RA_RNTI was received
@@ -318,7 +303,7 @@ void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms,
uint32_t *frame,
uint8_t *subframe);
/* \brief Get ULSCH harq_pid for Msg3 from RAR subframe. This returns n+k mod 10 (k>6) and corresponds to the rule in Section 6.1.1 from 36.213
/*! \brief Get ULSCH harq_pid for Msg3 from RAR subframe. This returns n+k mod 10 (k>6) and corresponds to the rule in Section 6.1.1 from 36.213
@param frame_parms Pointer to DL Frame Parameters
@param frame Frame index
@param current_subframe subframe of RAR transmission
@@ -326,20 +311,20 @@ void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms,
*/
uint8_t get_Msg3_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t current_subframe);
/* \brief Get ULSCH harq_pid from PHICH subframe
/*! \brief Get ULSCH harq_pid from PHICH subframe
@param frame_parms Pointer to DL Frame Parameters
@param subframe subframe of PHICH
@returns harq_pid (0 ... 7)
*/
/** \brief Function to indicate failure of contention resolution or RA procedure. It places the UE back in PRACH mode.
/*! \brief Function to indicate failure of contention resolution or RA procedure. It places the UE back in PRACH mode.
@param Mod_id Instance index of UE
@param CC_id Component Carrier Index
@param eNB_index Index of eNB
*/
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
/** \brief Function to indicate success of contention resolution or RA procedure.
/*! \brief Function to indicate success of contention resolution or RA procedure.
@param Mod_id Instance index of UE
@param CC_id Component Carrier Index
@param eNB_index Index of eNB
@@ -348,16 +333,15 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
uint8_t phich_subframe_to_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe);
/* \brief Get PDSCH subframe (n+k) from PDCCH subframe n using relationship from Table 8-2 from 36.213
/*! \brief Get PDSCH subframe (n+k) from PDCCH subframe n using relationship from Table 8-2 from 36.213
@param frame_parms Pointer to DL Frame Parameters
@param n subframe of PDCCH
@returns PDSCH subframe (0 ... 7) (note: this is n+k from Table 8-2)
*/
uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
//
/*!
\brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
/*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
@param frame_parms Pointer to DL frame parameter descriptor
@param harq_ack Pointer to dlsch_ue harq_ack status descriptor
@param subframe Subframe for UE transmission (n in 36.213)
@@ -366,8 +350,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
*/
uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK);
/*!
\brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6)
/*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6)
@param frame_parms Pointer to DL frame parameter descriptor
@param subframe Subframe for UE transmission (n in 36.213)
@param ACK_index TTI bundling index (0,1)
@@ -375,16 +358,14 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t
*/
uint8_t ul_ACK_subframe2_dl_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe,uint8_t ACK_index);
/*!
\brief Computes number of DL subframes represented by a particular ACK received on UL (M from Table 10.1-1 in 36.213, p. 69 in version 8.6)
/*! \brief Computes number of DL subframes represented by a particular ACK received on UL (M from Table 10.1-1 in 36.213, p. 69 in version 8.6)
@param frame_parms Pointer to DL frame parameter descriptor
@param subframe Subframe for UE transmission (n in 36.213)
@returns Number of DL subframes (M)
*/
uint8_t ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe);
/*!
\brief Indicates the SR TXOp in current subframe. Implements Table 10.1-5 from 36.213.
/*! \brief Indicates the SR TXOp in current subframe. Implements Table 10.1-5 from 36.213.
@param phy_vars_ue Pointer to UE variables
@param eNB_id ID of eNB which is to receive the SR
@param subframe index of next subframe
@@ -392,8 +373,7 @@ uint8_t ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subfram
*/
uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
/*!
\brief Indicates the SR TXOp in current subframe for eNB and particular UE index. Implements Table 10.1-5 from 36.213.
/*! \brief Indicates the SR TXOp in current subframe for eNB and particular UE index. Implements Table 10.1-5 from 36.213.
@param phy_vars_eNB Pointer to eNB variables
@param UE_id ID of UE which may be issuing the SR
@param subframe index of last subframe
@@ -401,16 +381,14 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
*/
uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t subframe);
/*!
\brief Gives the UL subframe corresponding to a PDDCH order in subframe n
/*! \brief Gives the UL subframe corresponding to a PDDCH order in subframe n
@param frame_parms Pointer to DL frame parameters
@param n subframe of PDCCH
@returns UL subframe corresponding to pdcch order
*/
uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
/*!
\brief Gives the UL frame corresponding to a PDDCH order in subframe n
/*! \brief Gives the UL frame corresponding to a PDDCH order in subframe n
@param frame_parms Pointer to DL frame parameters
@param frame Frame of received PDCCH
@param n subframe of PDCCH
@@ -431,11 +409,11 @@ int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_
void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance);
void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,uint16_t timing_advance);
unsigned int get_tx_amp(int gain_dBm, int gain_max_dBm);
unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
/** \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in
/*! \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in
subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch. For
TDD, this routine computes the complex procedure described in Section 10.1 of 36.213 (through tables 10.1-1,10.1-2)
@param phy_vars_ue Pointer to UE variables
@@ -451,7 +429,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *phy_vars_ue,
uint8_t *b,
uint8_t SR);
/** \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in
/*! \brief This function retrives the resource (n1_pucch) corresponding to a PDSCH transmission in
subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch. For
TDD, this routine computes the procedure described in Section 10.1 of 36.213 (through tables 10.1-1,10.1-2)
@param phy_vars_eNB Pointer to UE variables
@@ -472,8 +450,7 @@ void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB,
int16_t *n1_pucch3);
/*!
\brief This function retrieves the harq_pid of the corresponding DLSCH process and updates the error statistics of the DLSCH based on the received ACK info from UE along with the round index. It also performs the fine-grain rate-adaptation based on the error statistics derived from the ACK/NAK process.
/*! \brief This function retrieves the harq_pid of the corresponding DLSCH process and updates the error statistics of the DLSCH based on the received ACK info from UE along with the round index. It also performs the fine-grain rate-adaptation based on the error statistics derived from the ACK/NAK process.
@param UE_id Local UE index on which to act
@param subframe Index of subframe
@param phy_vars_eNB Pointer to eNB variables on which to act
@@ -490,8 +467,7 @@ void process_HARQ_feedback(uint8_t UE_id,
uint8_t pucch_sel,
uint8_t SR_payload);
/*!
\brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
/*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
@param Mod_id Local UE index on which to act
@param CC_id Component Carrier Index
@param eNB_index ID of eNB
@@ -499,7 +475,7 @@ void process_HARQ_feedback(uint8_t UE_id,
*/
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
/** \brief This function implements the power control mechanism for PUCCH from 36.213.
/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
@param phy_vars_ue PHY variables
@param subframe Index of subframe
@param eNB_id Index of eNB
@@ -508,7 +484,7 @@ UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
*/
int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt);
/** \brief This function implements the power control mechanism for PUCCH from 36.213.
/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
@param phy_vars_ue PHY variables
@param subframe Index of subframe
@param eNB_id Index of eNB
@@ -520,7 +496,7 @@ void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,u
int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
#ifdef LOCALIZATION
/** \brief This function collects eNB_UE stats and aggregate them in lists for localization
/*! \brief This function collects eNB_UE stats and aggregate them in lists for localization
@param phy_vars_ue PHY variables
@param UE_id Index of UE
@param frame Index of frame
@@ -542,7 +518,8 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,
int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid);
int16_t get_target_ul_rx_power(module_id_t module_idP, uint8_t CC_id);
int16_t get_target_pusch_rx_power(module_id_t module_idP, uint8_t CC_id);
int16_t get_target_pucch_rx_power(module_id_t module_idP, uint8_t CC_id);
int get_ue_active_harq_pid(uint8_t Mod_id,uint8_t CC_id,uint16_t rnti,int frame, uint8_t subframe,uint8_t *harq_pid,uint8_t *round,uint8_t ul_flag);
@@ -552,8 +529,8 @@ void dump_dlsch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint8_t
void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
/*@}*/
/**@}*/
#endif //OPENAIR_LTE
extern int slot_irq_handler(int irq, void *cookie);
+17 -17
View File
@@ -62,7 +62,7 @@ void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms,
if (*subframe>9) {
*subframe = *subframe-10;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
} else {
*frame=current_frame;
}
@@ -77,17 +77,17 @@ void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms,
case 4:
*subframe = 2;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
break;
case 5:
*subframe = 2;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
break;
case 9:
*subframe = 7;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
break;
}
} else if (frame_parms->tdd_config == 3) {
@@ -97,22 +97,22 @@ void get_Msg3_alloc(LTE_DL_FRAME_PARMS *frame_parms,
case 5:
case 6:
*subframe = 2;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
break;
case 7:
*subframe = 3;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
break;
case 8:
*subframe = 4;
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
break;
case 9:
*subframe = 2;
*frame = current_frame+2;
*frame = (current_frame+2) & 1023;
break;
}
}
@@ -126,14 +126,14 @@ void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char *subframe)
{
if (frame_parms->frame_type == FDD) {
// always retransmit in n+8
*subframe = current_subframe+8;
/* always retransmit in n+8 */
*subframe = current_subframe + 8;
if (*subframe>9) {
*subframe = *subframe-10;
*frame = current_frame+1;
if (*subframe > 9) {
*subframe = *subframe - 10;
*frame = (current_frame + 1) & 1023;
} else {
*frame=current_frame;
*frame = current_frame;
}
} else {
if (frame_parms->tdd_config == 1) {
@@ -141,12 +141,12 @@ void get_Msg3_alloc_ret(LTE_DL_FRAME_PARMS *frame_parms,
// original PUSCH in 3, PHICH in 9, ret in 3
// original PUSCH in 7, PHICH in 1 (S), ret in 7
// original PUSCH in 8, PHICH in 4, ret in 8
*frame = current_frame+1;
*frame = (current_frame+1) & 1023;
} else if (frame_parms->tdd_config == 3) {
// original PUSCH in 2, PHICH in 8, ret in 2 next frame
// original PUSCH in 3, PHICH in 9, ret in 3 next frame
// original PUSCH in 4, PHICH in 0, ret in 4 next frame
*frame=current_frame+1;
*frame=(current_frame+1) & 1023;
}
}
}
@@ -161,7 +161,7 @@ uint8_t get_Msg3_harq_pid(LTE_DL_FRAME_PARMS *frame_parms,
if (frame_parms->frame_type ==FDD) {
ul_subframe = (current_subframe>3) ? (current_subframe-4) : (current_subframe+6);
ul_frame = (current_subframe>3) ? (frame+1) : frame;
ul_frame = (current_subframe>3) ? ((frame+1)&1023) : frame;
} else {
switch (frame_parms->tdd_config) {
case 1:
+172 -74
View File
@@ -49,7 +49,7 @@
#include "SCHED/phy_procedures_emos.h"
#endif
#define DEBUG_PHY_PROC
//#define DEBUG_PHY_PROC (Already defined in cmake)
//#define DEBUG_ULSCH
//#ifdef OPENAIR2
@@ -64,7 +64,7 @@
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
# if defined(ENABLE_RAL)
# if ENABLE_RAL
# include "timer.h"
# endif
#endif
@@ -74,8 +74,6 @@
#define NS_PER_SLOT 500000
#define PUCCH 1
#define PUCCH1_THRES 15
#define PUCCH1a_THRES 15
extern int exit_openair;
//extern void do_OFDM_mod(mod_sym_t **txdataF, int32_t **txdata, uint32_t frame, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
@@ -161,6 +159,15 @@ int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
phy_vars_eNB->dlsch_eNB[i][0]->rnti = rnti;
phy_vars_eNB->ulsch_eNB[i]->rnti = rnti;
phy_vars_eNB->eNB_UE_stats[i].crnti = rnti;
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_below = 0;
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
LOG_I(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
phy_vars_eNB->rx_total_gain_eNB_dB,
phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH);
return(i);
}
}
@@ -172,10 +179,6 @@ int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction
{
uint8_t i;
#ifdef DEBUG_PHY_PROC
LOG_I(PHY,"eNB %d removing UE with rnti %x\n",phy_vars_eNB->Mod_id,rnti);
#endif
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti);
@@ -184,6 +187,9 @@ int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction
} else {
if (phy_vars_eNB->eNB_UE_stats[i].crnti==rnti) {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rnti);
#ifdef DEBUG_PHY_PROC
LOG_I(PHY,"eNB %d removing UE %d with rnti %x\n",phy_vars_eNB->Mod_id,i,rnti);
#endif
//msg("[PHY] UE_id %d\n",i);
clean_eNb_dlsch(phy_vars_eNB->dlsch_eNB[i][0], abstraction_flag);
clean_eNb_ulsch(phy_vars_eNB->ulsch_eNB[i],abstraction_flag);
@@ -221,12 +227,11 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
LTE_eNB_DLSCH_t *DLSCH_ptr;
LTE_eNB_ULSCH_t *ULSCH_ptr;
// uint8_t subframe_m4;
uint8_t ulsch_subframe,ulsch_frame;
uint8_t i;
int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
// int frame = PHY_vars_eNB_g[Mod_id][CC_id]->proc[sched_subframe].frame_tx;
// int subframe = PHY_vars_eNB_g[Mod_id][CC_id]->proc[sched_subframe].subframe_tx;
int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
int first_proc_found=0;
if (UE_id==-1) {
LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
@@ -236,42 +241,45 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
if (ul_flag == 0) {// this is a DL request
DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0];
/*
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d] get_ue_active_harq_pid: Frame %d subframe %d, current harq_id %d\n",
Mod_id,frame,subframe,DLSCH_ptr->harq_ids[subframe]);
#endif
*/
// switch on TDD or FDD configuration here later
*harq_pid = DLSCH_ptr->harq_ids[subframe];
if ((*harq_pid<DLSCH_ptr->Mdlharq) &&
((DLSCH_ptr->harq_processes[*harq_pid]->round > 0))) {
// set to no available process first
*harq_pid = -1;
*round = DLSCH_ptr->harq_processes[*harq_pid]->round;
LOG_D(PHY,"round %d\n",*round);
for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
if (DLSCH_ptr->harq_processes[i]!=NULL) {
if (DLSCH_ptr->harq_processes[i]->status != ACTIVE) {
// store first inactive process
if (first_proc_found == 0) {
first_proc_found = 1;
*harq_pid = i;
*round = 0;
LOG_D(PHY,"process %d is first free process\n",i);
}
else {
LOG_D(PHY,"process %d is free\n",i);
}
} else {
sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
if (sf2<=sf1)
sfdiff = sf1-sf2;
else // this happens when wrapping around 1024 frame barrier
sfdiff = 10240 + sf1-sf2;
LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff);
// else if ((subframe_m4==5) || (subframe_m4==6)) {
// *harq_pid = 0;//DLSCH_ptr->harq_ids[subframe_m4];//Ankit
// *round = DLSCH_ptr->harq_processes[*harq_pid]->round;
// }
} else {
// get first free harq_pid (i.e. round 0)
for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
if (DLSCH_ptr->harq_processes[i]!=NULL) {
if (DLSCH_ptr->harq_processes[i]->status != ACTIVE) {
*harq_pid = i;//0;//i; //(Ankit)
*round = 0;
return(0);
} else {
LOG_D(PHY,"process %d is active\n",i);
}
} else {
LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
return(-1);
}
if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms)
sfdiff_max = sfdiff;
*harq_pid = i;
*round = DLSCH_ptr->harq_processes[i]->round;
first_proc_found = 1;
}
}
} else { // a process is not defined
LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
return(-1);
}
}
LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
frame,subframe,*harq_pid);
} else { // This is a UL request
ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch_eNB[(uint32_t)UE_id];
@@ -312,10 +320,10 @@ int get_nCCE_offset(const unsigned char L, const int nCCE, const int common_dci,
if (common_dci == 1) {
// check CCE(0 ... L-1)
nb_candidates = (L==4) ? 4 : 2;
nb_candidates = min(nb_candidates,nCCE/L);
for (m = 0 ; m < nb_candidates ; m++) {
for (m = nb_candidates-1 ; m >=0 ; m--) {
search_space_free = 1;
for (l=0; l<L; l++) {
if (CCE_table[(m*L) + l] == 1) {
search_space_free = 0;
@@ -326,7 +334,6 @@ int get_nCCE_offset(const unsigned char L, const int nCCE, const int common_dci,
if (search_space_free == 1) {
for (l=0; l<L; l++)
CCE_table[(m*L)+l]=1;
return(m*L);
}
}
@@ -384,12 +391,18 @@ int get_nCCE_offset(const unsigned char L, const int nCCE, const int common_dci,
}
}
int16_t get_target_ul_rx_power(const module_id_t module_idP, const uint8_t CC_id)
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
//return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
}
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
//return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
}
#ifdef EMOS
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *phy_vars_eNB)
{
@@ -493,6 +506,9 @@ void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *phy_vars_eN
last_subframe_emos=0;
#ifdef EMOS_CHANNEL
//if (last_slot%2==1) // this is for all UL subframes
@@ -571,7 +587,7 @@ void fill_dci(DCI_PDU *DCI_pdu, uint8_t sched_subframe, PHY_VARS_eNB *phy_vars_e
switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
case 6:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_FDD_t;
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->type = 1;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
@@ -653,7 +669,7 @@ void fill_dci(DCI_PDU *DCI_pdu, uint8_t sched_subframe, PHY_VARS_eNB *phy_vars_e
case 100:
if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) {
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_10MHz_FDD_t;
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_20MHz_FDD_t;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->type = 1;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->vrb_type = 0;
((DCI1A_20MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3);
@@ -1225,7 +1241,7 @@ int QPSK2[4]= {AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),(
#if defined(ENABLE_ITTI)
# if defined(ENABLE_RAL)
# if ENABLE_RAL
extern PHY_MEASUREMENTS PHY_measurements;
void phy_eNB_lte_measurement_thresholds_test_and_report(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP, uint16_t valP)
@@ -1374,7 +1390,7 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
#ifdef Rel10
MCH_PDU *mch_pduP;
MCH_PDU mch_pdu;
uint8_t sync_area=255;
// uint8_t sync_area=255;
#endif
#if defined(SMBV) && !defined(EXMIMO)
// counts number of allocations in subframe
@@ -1518,10 +1534,12 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
subframe<<1,0);
generate_pilots_slot(phy_vars_eNB,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
(subframe<<1)+1,0);
if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_DL)
generate_pilots_slot(phy_vars_eNB,
phy_vars_eNB->lte_eNB_common_vars.txdataF[0],
AMP,
(subframe<<1)+1,0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
// First half of PSS/SSS (FDD)
@@ -1832,7 +1850,8 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"] SI generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id);
#endif
generate_eNB_dlsch_params_from_dci(subframe,
generate_eNB_dlsch_params_from_dci(frame,
subframe,
&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].format,
@@ -1872,7 +1891,8 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %"PRIu8"] RA generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id);
#endif
generate_eNB_dlsch_params_from_dci(subframe,
generate_eNB_dlsch_params_from_dci(frame,
subframe,
&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].format,
@@ -1933,7 +1953,8 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
}
#endif
generate_eNB_dlsch_params_from_dci(subframe,
generate_eNB_dlsch_params_from_dci(frame,
subframe,
&DCI_pdu->dci_alloc[i].dci_pdu[0],
DCI_pdu->dci_alloc[i].rnti,
DCI_pdu->dci_alloc[i].format,
@@ -1999,7 +2020,7 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
if (harq_pid==255) {
LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx);
mac_exit_wrapper("Invalid harq_pid (255) detected");
//mac_exit_wrapper("Invalid harq_pid (255) detected");
return; // not reached
}
@@ -2171,6 +2192,8 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
//FIXME: The code below is commented as next_slot is not defined which results in failed compilation
/*
LOG_D(PHY,"[eNB %"PRIu8"][SI] Frame %d, slot %d: Calling generate_dlsch (SI) with input size = %"PRIu16", num_pdcch_symbols %"PRIu8"\n",
phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot, input_buffer_length,num_pdcch_symbols); // FIXME this code is broken (next_slot?)
@@ -2178,6 +2201,7 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
LOG_T(PHY,"%x.",i,DLSCH_pdu[i]);// FIXME this code is broken (number of arguments)
LOG_T(PHY,"\n");
*/
#endif
#endif
@@ -2259,7 +2283,10 @@ void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_e
LOG_T(PHY,"%x.",dlsch_input_buffer[i]);
LOG_T(PHY,"\n");
*/
UE_id = add_ue(crnti,phy_vars_eNB);
if (crnti!=0)
UE_id = add_ue(crnti,phy_vars_eNB);
else
UE_id = -1;
if (UE_id==-1) {
LOG_W(PHY,"[eNB] Max user count reached.\n");
@@ -2675,13 +2702,22 @@ void process_HARQ_feedback(uint8_t UE_id,
dl_harq_pid[0] = dlsch->harq_ids[subframe_m4];
M=1;
if (pusch_flag == 1)
if (pusch_flag == 1) {
dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0];
else
if (dlsch->subframe_tx[subframe_m4]==1)
LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUSCH for subframe %d\n",phy_vars_eNB->Mod_id,
frame,dlsch_ACK[0],subframe_m4);
}
else {
dlsch_ACK[0] = pucch_payload[0];
LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUCCH for subframe %d\n",phy_vars_eNB->Mod_id,
frame,dlsch_ACK[0],subframe_m4);
/*
if (dlsch_ACK[0]==0)
AssertFatal(0,"Exiting on NAK on PUCCH\n");
*/
}
LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d for subframe %d\n",phy_vars_eNB->Mod_id,
frame,dlsch_ACK[0],subframe_m4);
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE(
@@ -3067,7 +3103,7 @@ void prach_procedures(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t
memset(&preamble_delay_list[0],0,64*sizeof(uint16_t));
if (abstraction_flag == 0) {
LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",phy_vars_eNB->Mod_id,
LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",phy_vars_eNB->Mod_id,
frame,subframe,dB_fixed(signal_energy(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],512)) - phy_vars_eNB->rx_total_gain_eNB_dB);
// LOG_I(PHY,"[eNB %d][RAPROC] PRACH: rootSequenceIndex %d, prach_ConfigIndex %d, zeroCorrelationZoneConfig %d, highSpeedFlag %d, prach_FreqOffset %d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset);
@@ -3129,21 +3165,46 @@ void prach_procedures(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits
//phy_vars_eNb->eNB_UE_stats[(uint32_t)UE_id].mode = PRACH;
phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].sector = 0;
LOG_I(PHY,"[eNB %d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n",
phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
subframe,
UE_id,
preamble_max,
preamble_energy_max/10,
preamble_energy_max%10,
preamble_delay_list[preamble_max]);
#ifdef OPENAIR2
uint8_t update_TA=4;
switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) {
case 6:
update_TA = 16;
break;
case 25:
update_TA = 4;
break;
case 50:
update_TA = 2;
break;
case 100:
update_TA = 1;
break;
}
mac_xface->initiate_ra_proc(phy_vars_eNB->Mod_id,
phy_vars_eNB->CC_id,
frame,
preamble_max,
preamble_delay_list[preamble_max],
0,subframe,0);
preamble_delay_list[preamble_max]*update_TA,
0,subframe,0);
#endif
} else {
MSC_LOG_EVENT(MSC_PHY_ENB, "0 RA Failed add user, too many");
@@ -3197,6 +3258,13 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_
LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,frame, subframe);
#endif
/*
#ifdef OAI_USRP
for (aa=0;aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx;aa++)
rescale(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][aa][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],
phy_vars_eNB->lte_frame_parms.samples_per_tti);
#endif
*/
if (abstraction_flag == 0) {
remove_7_5_kHz(phy_vars_eNB,subframe<<1);
remove_7_5_kHz(phy_vars_eNB,(subframe<<1)+1);
@@ -3346,9 +3414,9 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_
round = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round;
#ifdef DEBUG_PHY_PROC
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Scheduling PUSCH/ULSCH Reception for rnti %x\n",
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Scheduling PUSCH/ULSCH Reception for rnti %x (UE_id %d)\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,phy_vars_eNB->ulsch_eNB[i]->rnti);
frame,subframe,phy_vars_eNB->ulsch_eNB[i]->rnti,i);
#endif
#ifdef DEBUG_PHY_PROC
@@ -3534,6 +3602,20 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1,
phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx-1);
LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
ret);
if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round ==
phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx) {
LOG_I(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n",
@@ -3621,10 +3703,24 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_
}
} // ulsch in error
else {
LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe);
if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) {
LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe);
LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
phy_vars_eNB->Mod_id,harq_pid,
frame,subframe,
phy_vars_eNB->ulsch_eNB[i]->rnti,
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]),
dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]),
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0],
phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0],
phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0],
phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1],
ret);
}
#if defined(MESSAGE_CHART_GENERATOR_PHY)
MSC_LOG_RX_MESSAGE(
MSC_PHY_ENB,MSC_PHY_UE,
@@ -3893,6 +3989,8 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_
// if SR was detected, use the n1_pucch from SR, else use n1_pucch0
n1_pucch0 = (SR_payload==1) ? phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex:n1_pucch0;
LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,SR_payload);
if (abstraction_flag == 0)
metric0 = rx_pucch(phy_vars_eNB,
pucch_format1a,
@@ -4351,7 +4449,7 @@ void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **phy_vars_eNB,u
Mod_id = instance;
switch (ITTI_MSG_ID(msg_p)) {
# if defined(ENABLE_RAL)
# if ENABLE_RAL
case TIMER_HAS_EXPIRED:
// check if it is a measurement timer
File diff suppressed because it is too large Load Diff
+8 -9
View File
@@ -53,14 +53,13 @@ int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id
if ((pucch_fmt == pucch_format1a) ||
(pucch_fmt == pucch_format1b)) { // Update g_pucch based on TPC/delta_PUCCH received in PDCCH for this process
harq_pid = phy_vars_ue->dlsch_ue[eNB_id][0]->harq_ack[subframe].harq_id;
phy_vars_ue->g_pucch[eNB_id] += phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->delta_PUCCH;
//this is now done in dci_tools
//phy_vars_ue->g_pucch[eNB_id] += phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->delta_PUCCH;
}
phy_vars_ue->g_pucch[eNB_id] = 0;
Po_PUCCH = get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id)+
phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
phy_vars_ue->g_pucch[eNB_id];
phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
phy_vars_ue->dlsch_ue[eNB_id][0]->g_pucch;
switch (pucch_fmt) {
case pucch_format1:
@@ -97,21 +96,21 @@ int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id
}
if (pucch_fmt!=pucch_format1) {
LOG_D(PHY,"[UE %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
LOG_I(PHY,"[UE %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
phy_vars_ue->Mod_id,
phy_vars_ue->dlsch_ue[eNB_id][0]->rnti,phy_vars_ue->frame_tx,subframe,
Po_PUCCH,
phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id),
phy_vars_ue->g_pucch[eNB_id]);
phy_vars_ue->dlsch_ue[eNB_id][0]->g_pucch);
} else {
LOG_D(PHY,"[UE %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
LOG_I(PHY,"[UE %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
phy_vars_ue->Mod_id,
phy_vars_ue->dlsch_ue[eNB_id][0]->rnti,phy_vars_ue->frame_tx,subframe,
Po_PUCCH,
phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
get_PL(phy_vars_ue->Mod_id,phy_vars_ue->CC_id,eNB_id),
phy_vars_ue->g_pucch[eNB_id]);
phy_vars_ue->dlsch_ue[eNB_id][0]->g_pucch);
}
return(Po_PUCCH);
+2 -2
View File
@@ -175,14 +175,14 @@ void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,u
phy_vars_ue->ulsch_ue[eNB_id]->Po_PUSCH += ((alpha_lut[phy_vars_ue->lte_frame_parms.ul_power_control_config_common.alpha]*PL)/100);
phy_vars_ue->ulsch_ue[eNB_id]->Po_PUSCH += phy_vars_ue->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
phy_vars_ue->ulsch_ue[eNB_id]->PHR = phy_vars_ue->tx_power_max_dBm-phy_vars_ue->ulsch_ue[eNB_id]->Po_PUSCH; // 15 dBm, FIX ME should be P0_max
phy_vars_ue->ulsch_ue[eNB_id]->PHR = phy_vars_ue->tx_power_max_dBm-phy_vars_ue->ulsch_ue[eNB_id]->Po_PUSCH;
if (phy_vars_ue->ulsch_ue[eNB_id]->PHR < -23)
phy_vars_ue->ulsch_ue[eNB_id]->PHR = -23;
else if (phy_vars_ue->ulsch_ue[eNB_id]->PHR > 40)
phy_vars_ue->ulsch_ue[eNB_id]->PHR = 40;
LOG_I(PHY,"[UE %d][PUSCH %d] frame %d, subframe %d: Po_PUSCH %d dBm : tx power %d, Po_NOMINAL_PUSCH %d,log10(NPRB) %f,PHR %d, PL %d, alpha*PL %f,delta_IF %f,f_pusch %d\n",
LOG_D(PHY,"[UE %d][PUSCH %d] frame %d, subframe %d: Po_PUSCH %d dBm : tx power %d, Po_NOMINAL_PUSCH %d,log10(NPRB) %f,PHR %d, PL %d, alpha*PL %f,delta_IF %f,f_pusch %d\n",
phy_vars_ue->Mod_id,harq_pid,phy_vars_ue->frame_tx,subframe,
phy_vars_ue->ulsch_ue[eNB_id]->Po_PUSCH,
phy_vars_ue->tx_power_max_dBm,
@@ -75,7 +75,7 @@ int netlink_init(void)
printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd);
#if !defined(USE_PDCP_NETLINK_QUEUES)
#if !defined(PDCP_USE_NETLINK_QUEUES)
ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK);
if (ret == -1) {
+52 -28
View File
@@ -135,7 +135,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_tx_phy, unsigned char N_
lte_frame_parms->nb_antennas_tx = N_tx;
lte_frame_parms->nb_antennas_rx = N_rx;
lte_frame_parms->nb_antennas_tx_eNB = N_tx;
lte_frame_parms->phich_config_common.phich_resource = oneSixth;
lte_frame_parms->phich_config_common.phich_resource = one;
lte_frame_parms->tdd_config = tdd_config;
lte_frame_parms->frame_type = (fdd_flag==1)?0 : 1;
// lte_frame_parms->Csrs = 2;
@@ -240,8 +240,8 @@ void do_OFDM_mod_l(mod_sym_t **txdataF, int32_t **txdata, uint16_t next_slot, LT
int main(int argc, char **argv)
{
char c;
int k,i,aa,aarx,aatx,re;
int c;
int k,i,aa,aarx,aatx;
int s,Kr,Kr_bytes;
@@ -356,12 +356,24 @@ int main(int argc, char **argv)
LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
uint8_t Kmimo;
FILE *proc_fd = NULL;
char buf[64];
opp_enabled=1; // to enable the time meas
cpu_freq_GHz = (double)get_cpu_freq_GHz();
#if defined(__arm__)
proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
if(!proc_fd)
printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
else {
while(fgets(buf, 63, proc_fd))
printf("%s", buf);
}
fclose(proc_fd);
cpu_freq_GHz = ((double)atof(buf))/1e6;
#else
cpu_freq_GHz = get_cpu_freq_GHz();
#endif
printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
//signal(SIGSEGV, handler);
@@ -533,6 +545,7 @@ int main(int argc, char **argv)
if ((transmission_mode!=1) &&
(transmission_mode!=2) &&
(transmission_mode!=3) &&
(transmission_mode!=4) &&
(transmission_mode!=5) &&
(transmission_mode!=6) &&
(transmission_mode!=7)) {
@@ -681,7 +694,7 @@ int main(int argc, char **argv)
printf("-z Number of RX antennas used in UE\n");
printf("-t MCS of interfering UE\n");
printf("-R Number of HARQ rounds (fixed)\n");
printf("-M Turns on calibration mode for abstraction.\n");
printf("-A Turns on calibration mode for abstraction.\n");
printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n");
printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n");
printf("-I Input filename for TrCH data (binary)\n");
@@ -758,18 +771,18 @@ int main(int argc, char **argv)
lte_gold_ue_spec_port5(PHY_vars_UE->lte_gold_uespec_port5_table,Nid_cell,n_rnti);
beamforming_weights = (int32_t **)malloc(12*N_RB_DL*sizeof(int32_t*));
for(re=0;re<12*N_RB_DL;re++){
beamforming_weights[re]=(int32_t *)malloc(n_tx_phy*sizeof(int32_t));
for(i=0;i<12*N_RB_DL;i++){
beamforming_weights[i]=(int32_t *)malloc(n_tx_phy*sizeof(int32_t));
for(aa=0;aa<n_tx_phy;aa++){
//tmp
if (n_tx_phy==1)
beamforming_weights[re][aa] = 0x00007fff;
beamforming_weights[i][aa] = 0x00007fff;
else if (n_tx_phy==4)
beamforming_weights[re][aa] = 0x00007fff>>1;
beamforming_weights[i][aa] = 0x00007fff>>1;
else if (n_tx_phy==16)
beamforming_weights[re][aa] = 0x00007fff>>2;
beamforming_weights[i][aa] = 0x00007fff>>2;
else if (n_tx_phy==64)
beamforming_weights[re][aa] = 0x00007fff>>3;
beamforming_weights[i][aa] = 0x00007fff>>3;
}
}
printf("***n_tx_phy=%d,n_tx_phy>>2=%d,beamforming_weights=%d\n",n_tx_phy,n_tx_phy>>2,beamforming_weights[0][0]);
@@ -1203,6 +1216,7 @@ int main(int argc, char **argv)
printf("Generating dlsch params for user %d\n",k);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
n_rnti+k,
format1,
@@ -1345,6 +1359,7 @@ int main(int argc, char **argv)
printf("Generating dlsch params for user %d\n",k);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
SI_RNTI,
format1A,
@@ -1511,6 +1526,7 @@ int main(int argc, char **argv)
printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
n_rnti+k,
format2A,
@@ -1650,6 +1666,7 @@ int main(int argc, char **argv)
printf("Generating dlsch params for user %d\n",k);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
SI_RNTI,
format1A,
@@ -1817,6 +1834,7 @@ int main(int argc, char **argv)
printf("Generating dlsch params for user %d\n",k);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
n_rnti+k,
format2,
@@ -1956,6 +1974,7 @@ int main(int argc, char **argv)
printf("Generating dlsch params for user %d\n",k);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
SI_RNTI,
format1A,
@@ -1984,6 +2003,7 @@ int main(int argc, char **argv)
dci_alloc[num_dci].nCCE = 4*k;
printf("Generating dlsch params for user %d\n",k);
generate_eNB_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu2_1E[k],
n_rnti+k,
format1E_2A_M10PRB,
@@ -2049,7 +2069,8 @@ int main(int argc, char **argv)
if (input_trch_file==0) {
for (i=0; i<input_buffer_length0; i++) {
input_buffer0[k][i]= (unsigned char)(taus()&0xff);
//input_buffer0[k][i] = (unsigned char)(i&0xff);
input_buffer0[k][i] = (unsigned char)(taus()&0xff);
}
for (i=0; i<input_buffer_length1; i++) {
@@ -2890,8 +2911,7 @@ PMI_FEEDBACK:
if (PHY_vars_eNB->nb_antennas_tx_phy>1)// to be updated
write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],
nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1);
}
}
tx_lev = 0;
for (aa=0; aa<PHY_vars_eNB->nb_antennas_tx_phy; aa++) {
@@ -3109,16 +3129,15 @@ PMI_FEEDBACK:
no_prefix if 1 prefix is removed by HW
*/
if(Ns==(2*subframe) || Ns==(2*subframe+1)) {
start_meas(&PHY_vars_UE->ofdm_demod_stats);
slot_fep(PHY_vars_UE,
l,
Ns%20,
0,
0);
stop_meas(&PHY_vars_UE->ofdm_demod_stats);
}
//write_output("rxsigF0.m","rxsF0", &PHY_vars_UE->lte_ue_common_vars.rxdataF[0][0],PHY_vars_UE->lte_frame_parms.ofdm_symbol_size*nsymb,1,1);
start_meas(&PHY_vars_UE->ofdm_demod_stats);
slot_fep(PHY_vars_UE,
l,
Ns%20,
0,
0,
0);
stop_meas(&PHY_vars_UE->ofdm_demod_stats);
if (PHY_vars_UE->perfect_ce==1) {
if (awgn_flag==0) {
@@ -3254,6 +3273,7 @@ PMI_FEEDBACK:
if ((dci_alloc_rx[i].rnti == n_rnti) &&
(generate_ue_dlsch_params_from_dci(0,
subframe,
dci_alloc_rx[i].dci_pdu,
dci_alloc_rx[i].rnti,
dci_alloc_rx[i].format,
@@ -3266,7 +3286,7 @@ PMI_FEEDBACK:
//dump_dci(&PHY_vars_UE->lte_frame_parms,&dci_alloc_rx[i]);
coded_bits_per_codeword = get_G(&PHY_vars_eNB->lte_frame_parms,
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->nb_rb,
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc,
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->rb_alloc_even,
get_Qm(PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->mcs),
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid]->Nl,
PHY_vars_UE->lte_ue_pdcch_vars[0]->num_pdcch_symbols,
@@ -3316,6 +3336,7 @@ PMI_FEEDBACK:
case 2:
case 7:
generate_ue_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
(common_flag==0)? C_RNTI : SI_RNTI,
(common_flag==0)? format1 : format1A,
@@ -3332,6 +3353,7 @@ PMI_FEEDBACK:
case 3:
// printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->round,PHY_vars_UE->dlsch_ue[0][0]->harq_processes[0]->first_tx);
generate_ue_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
(common_flag==0)? C_RNTI : SI_RNTI,
(common_flag==0)? format2A : format1A,
@@ -3346,6 +3368,7 @@ PMI_FEEDBACK:
case 4:
generate_ue_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu_1[0],
(common_flag==0)? C_RNTI : SI_RNTI,
(common_flag==0)? format2 : format1A,
@@ -3360,6 +3383,7 @@ PMI_FEEDBACK:
case 5:
case 6:
generate_ue_dlsch_params_from_dci(0,
subframe,
&DLSCH_alloc_pdu2_1E[0],
C_RNTI,
format1E_2A_M10PRB,
@@ -3627,7 +3651,7 @@ PMI_FEEDBACK:
dlsch0_ue_harq = PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid];
dlsch0_eNB_harq = PHY_vars_UE->dlsch_eNB[eNB_id]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid];
dlsch0_eNB_harq->mimo_mode = LARGE_CDD;
dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc[0];
dlsch0_eNB_harq->rb_alloc[0] = dlsch0_ue_harq->rb_alloc_even[0];
dlsch0_eNB_harq->nb_rb = dlsch0_ue_harq->nb_rb;
dlsch0_eNB_harq->mcs = dlsch0_ue_harq->mcs;
dlsch0_eNB_harq->rvidx = dlsch0_ue_harq->rvidx;
+13 -5
View File
@@ -140,6 +140,7 @@ int main(int argc, char **argv)
double **s_re,**s_im,**r_re,**r_im;
double iqim = 0.0;
int subframe=1;
int sched_subframe;
char fname[40];//, vname[40];
uint8_t transmission_mode = 1,n_tx=1,n_rx=2;
uint16_t Nid_cell=0;
@@ -316,6 +317,9 @@ int main(int argc, char **argv)
}
}
sched_subframe = (subframe+9)%10;
if (awgn_flag == 1)
channel_model = AWGN;
@@ -444,7 +448,8 @@ int main(int argc, char **argv)
for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
PHY_vars_UE->frame_tx=0;
PHY_vars_eNB->proc[subframe].frame_tx=0;
PHY_vars_eNB->proc[sched_subframe].frame_tx=0;
PHY_vars_eNB->proc[sched_subframe].subframe_tx=subframe;
errs[0]=0;
errs[1]=0;
@@ -467,7 +472,8 @@ int main(int argc, char **argv)
eNB2UE->first_run = 1;
memset(&PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(mod_sym_t));
generate_mch(PHY_vars_eNB,subframe,input_buffer,0);
generate_mch(PHY_vars_eNB,sched_subframe,input_buffer,0);
PHY_ofdm_mod(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0], // input,
txdata[0], // output
@@ -477,7 +483,7 @@ int main(int argc, char **argv)
CYCLIC_PREFIX);
if (n_frames==1) {
write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],
write_output("txsigF0.m","txsF0", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],
nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1);
//if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1)
//write_output("txsigF1.m","txsF1", &PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size],nsymb*PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size,1,1);
@@ -548,10 +554,12 @@ int main(int argc, char **argv)
PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->G = get_G(&PHY_vars_UE->lte_frame_parms,
PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->nb_rb,
PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->rb_alloc,
PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->rb_alloc_even,
get_Qm(PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->mcs),
1,2,
PHY_vars_UE->frame_tx,subframe,0);
PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->Qm = get_Qm(PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->mcs);
dlsch_unscrambling(&PHY_vars_UE->lte_frame_parms,1,PHY_vars_UE->dlsch_ue_MCH[0],
PHY_vars_UE->dlsch_ue_MCH[0]->harq_processes[0]->G,
PHY_vars_UE->lte_ue_pdsch_vars_MCH[0]->llr[0],0,subframe<<1);
@@ -571,7 +579,7 @@ int main(int argc, char **argv)
errs[0]++;
PHY_vars_UE->frame_tx++;
PHY_vars_eNB->proc[subframe].frame_tx++;
PHY_vars_eNB->proc[sched_subframe].frame_tx++;
}
printf("errors %d/%d (Pe %e)\n",errs[round],trials,(double)errs[round]/trials);
+4 -2
View File
@@ -992,7 +992,8 @@ int main(int argc, char **argv)
l%(PHY_vars_eNb->lte_frame_parms.symbols_per_tti/2),
l/(PHY_vars_eNb->lte_frame_parms.symbols_per_tti/2),
0,
0);
0,
0);
if (l==0) {
@@ -1033,7 +1034,8 @@ int main(int argc, char **argv)
lte_est_freq_offset(PHY_vars_UE->lte_ue_common_vars.dl_ch_estimates[0],
&PHY_vars_UE->lte_frame_parms,
l,
&freq_offset);
&freq_offset,
1);
}
if (l==((PHY_vars_eNb->lte_frame_parms.Ncp==0)?10:9)) {
+3 -3
View File
@@ -49,7 +49,6 @@
#include "PHY/TOOLS/lte_phy_scope.h"
#endif
#define N_TRIALS 100
PHY_VARS_eNB *PHY_vars_eNB,*PHY_vars_eNB1,*PHY_vars_eNB2;
@@ -89,7 +88,7 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi
lte_frame_parms->nb_antennas_tx_eNB = N_tx;
lte_frame_parms->nb_antennas_tx = N_tx;
lte_frame_parms->nb_antennas_rx = N_rx;
lte_frame_parms->phich_config_common.phich_resource = oneSixth; //half
lte_frame_parms->phich_config_common.phich_resource = one; //half
lte_frame_parms->tdd_config = tdd_config;
lte_frame_parms->frame_type = frame_type;
@@ -1189,7 +1188,8 @@ int main(int argc, char **argv)
l%(PHY_vars_eNB->lte_frame_parms.symbols_per_tti/2),
(2*subframe)+(l/(PHY_vars_eNB->lte_frame_parms.symbols_per_tti/2)),
0,
0);
0,
0);
if (PHY_vars_UE->perfect_ce == 1) {
if (awgn_flag==0) {
+1 -1
View File
@@ -554,7 +554,7 @@ int main(int argc, char **argv)
for (i=1; i<64; i++) {
if (preamble_energy_max < preamble_energy_list[i]) {
// printf("preamble %d => %d\n",i,preamble_energy_list[i]);
// printf("preamble %d => %d\n",i,preamble_energy_list[i]);
preamble_energy_max = preamble_energy_list[i];
preamble_max = i;
}
+5 -3
View File
@@ -44,6 +44,7 @@
#include "SCHED/defs.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"
#include "intertask_interface_init.h"
#include "OCG_vars.h"
#include "UTIL/LOG/log_extern.h"
@@ -157,7 +158,7 @@ int main(int argc, char **argv)
int32_t stat;
double stat_no_sig,stat_sig;
uint8_t N0=40;
uint8_t pucch1_thres=13;
uint8_t pucch1_thres=10;
uint16_t n1_pucch = 0;
uint16_t n2_pucch = 0;
@@ -362,6 +363,7 @@ int main(int argc, char **argv)
}
logInit();
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
g_log->log_component[PHY].level = LOG_DEBUG;
g_log->log_component[PHY].flag = LOG_HIGH;
@@ -573,11 +575,11 @@ int main(int argc, char **argv)
sig=1;
} else {
if (trial<(n_frames>>1)) {
// printf("no sig =>");
//printf("no sig =>");
sig= 0;
} else {
sig=1;
// printf("sig =>");
//printf("sig =>");
pucch_tx++;
}
}
+222 -222
View File
@@ -1,222 +1,222 @@
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "defs.h"
#include "SIMULATION/RF/defs.h"
//#define DEBUG_CH
uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
{
random_channel(desc,0);
return(1);
}
#define CHANNEL_SSE
#ifdef CHANNEL_SSE
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
{
int i,ii,j,l;
int length1, length2, tail;
__m128d rx_tmp128_re_f,rx_tmp128_im_f,rx_tmp128_re,rx_tmp128_im, rx_tmp128_1,rx_tmp128_2,rx_tmp128_3,rx_tmp128_4,tx128_re,tx128_im,ch128_x,ch128_y,pathloss128;
double path_loss = pow(10,desc->path_loss_dB/20);
int dd = abs(desc->channel_offset);
pathloss128 = _mm_set1_pd(path_loss);
#ifdef DEBUG_CH
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
start_meas(&desc->convolution);
#ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
}
printf("\n");
#endif
tail = ((int)length-dd)%2;
if(tail)
length1 = ((int)length-dd)-1;
else
length1 = ((int)length-dd);
length2 = length1/2;
for (i=0; i<length2; i++) { //
for (ii=0; ii<desc->nb_rx; ii++) {
// rx_tmp.x = 0;
// rx_tmp.y = 0;
rx_tmp128_re_f = _mm_setzero_pd();
rx_tmp128_im_f = _mm_setzero_pd();
for (j=0; j<desc->nb_tx; j++) {
for (l = 0; l<(int)desc->channel_length; l++) {
if ((i>=0) && (i-l)>=0) { //SIMD correct only if length1 > 2*channel_length...which is almost always satisfied
// tx.x = tx_sig_re[j][i-l];
// tx.y = tx_sig_im[j][i-l];
tx128_re = _mm_loadu_pd(&tx_sig_re[j][2*i-l]); // tx_sig_re[j][i-l+1], tx_sig_re[j][i-l]
tx128_im = _mm_loadu_pd(&tx_sig_im[j][2*i-l]);
} else {
//tx.x =0;
//tx.y =0;
tx128_re = _mm_setzero_pd();
tx128_im = _mm_setzero_pd();
}
ch128_x = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].x);
ch128_y = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp128_1 = _mm_mul_pd(tx128_re,ch128_x);
rx_tmp128_2 = _mm_mul_pd(tx128_re,ch128_y);
rx_tmp128_3 = _mm_mul_pd(tx128_im,ch128_x);
rx_tmp128_4 = _mm_mul_pd(tx128_im,ch128_y);
rx_tmp128_re = _mm_sub_pd(rx_tmp128_1,rx_tmp128_4);
rx_tmp128_im = _mm_add_pd(rx_tmp128_2,rx_tmp128_3);
rx_tmp128_re_f = _mm_add_pd(rx_tmp128_re_f,rx_tmp128_re);
rx_tmp128_im_f = _mm_add_pd(rx_tmp128_im_f,rx_tmp128_im);
} //l
} // j
//rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
//rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
rx_tmp128_re_f = _mm_mul_pd(rx_tmp128_re_f,pathloss128);
rx_tmp128_im_f = _mm_mul_pd(rx_tmp128_im_f,pathloss128);
_mm_storeu_pd(&rx_sig_re[ii][2*i+dd],rx_tmp128_re_f); // max index: length-dd -1 + dd = length -1
_mm_storeu_pd(&rx_sig_im[ii][2*i+dd],rx_tmp128_im_f);
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
} // ii
} // i
stop_meas(&desc->convolution);
}
#else
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
{
int i,ii,j,l;
struct complex rx_tmp,tx;
double path_loss = pow(10,desc->path_loss_dB/20);
int dd;
dd = abs(desc->channel_offset);
#ifdef DEBUG_CH
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
#ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
}
printf("\n");
#endif
for (i=0; i<((int)length-dd); i++) {
for (ii=0; ii<desc->nb_rx; ii++) {
rx_tmp.x = 0;
rx_tmp.y = 0;
for (j=0; j<desc->nb_tx; j++) {
for (l = 0; l<(int)desc->channel_length; l++) {
if ((i>=0) && (i-l)>=0) {
tx.x = tx_sig_re[j][i-l];
tx.y = tx_sig_im[j][i-l];
} else {
tx.x =0;
tx.y =0;
}
rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
} //l
} // j
rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
} // ii
} // i
}
#endif
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "defs.h"
#include "SIMULATION/RF/defs.h"
//#define DEBUG_CH
uint8_t multipath_channel_nosigconv(channel_desc_t *desc)
{
random_channel(desc,0);
return(1);
}
//#define CHANNEL_SSE
#ifdef CHANNEL_SSE
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
{
int i,ii,j,l;
int length1, length2, tail;
__m128d rx_tmp128_re_f,rx_tmp128_im_f,rx_tmp128_re,rx_tmp128_im, rx_tmp128_1,rx_tmp128_2,rx_tmp128_3,rx_tmp128_4,tx128_re,tx128_im,ch128_x,ch128_y,pathloss128;
double path_loss = pow(10,desc->path_loss_dB/20);
int dd = abs(desc->channel_offset);
pathloss128 = _mm_set1_pd(path_loss);
#ifdef DEBUG_CH
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
start_meas(&desc->convolution);
#ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
}
printf("\n");
#endif
tail = ((int)length-dd)%2;
if(tail)
length1 = ((int)length-dd)-1;
else
length1 = ((int)length-dd);
length2 = length1/2;
for (i=0; i<length2; i++) { //
for (ii=0; ii<desc->nb_rx; ii++) {
// rx_tmp.x = 0;
// rx_tmp.y = 0;
rx_tmp128_re_f = _mm_setzero_pd();
rx_tmp128_im_f = _mm_setzero_pd();
for (j=0; j<desc->nb_tx; j++) {
for (l = 0; l<(int)desc->channel_length; l++) {
if ((i>=0) && (i-l)>=0) { //SIMD correct only if length1 > 2*channel_length...which is almost always satisfied
// tx.x = tx_sig_re[j][i-l];
// tx.y = tx_sig_im[j][i-l];
tx128_re = _mm_loadu_pd(&tx_sig_re[j][2*i-l]); // tx_sig_re[j][i-l+1], tx_sig_re[j][i-l]
tx128_im = _mm_loadu_pd(&tx_sig_im[j][2*i-l]);
} else {
//tx.x =0;
//tx.y =0;
tx128_re = _mm_setzero_pd();
tx128_im = _mm_setzero_pd();
}
ch128_x = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].x);
ch128_y = _mm_set1_pd(desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
// rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp128_1 = _mm_mul_pd(tx128_re,ch128_x);
rx_tmp128_2 = _mm_mul_pd(tx128_re,ch128_y);
rx_tmp128_3 = _mm_mul_pd(tx128_im,ch128_x);
rx_tmp128_4 = _mm_mul_pd(tx128_im,ch128_y);
rx_tmp128_re = _mm_sub_pd(rx_tmp128_1,rx_tmp128_4);
rx_tmp128_im = _mm_add_pd(rx_tmp128_2,rx_tmp128_3);
rx_tmp128_re_f = _mm_add_pd(rx_tmp128_re_f,rx_tmp128_re);
rx_tmp128_im_f = _mm_add_pd(rx_tmp128_im_f,rx_tmp128_im);
} //l
} // j
//rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
//rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
rx_tmp128_re_f = _mm_mul_pd(rx_tmp128_re_f,pathloss128);
rx_tmp128_im_f = _mm_mul_pd(rx_tmp128_im_f,pathloss128);
_mm_storeu_pd(&rx_sig_re[ii][2*i+dd],rx_tmp128_re_f); // max index: length-dd -1 + dd = length -1
_mm_storeu_pd(&rx_sig_im[ii][2*i+dd],rx_tmp128_im_f);
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
} // ii
} // i
stop_meas(&desc->convolution);
}
#else
void multipath_channel(channel_desc_t *desc,
double **tx_sig_re,
double **tx_sig_im,
double **rx_sig_re,
double **rx_sig_im,
uint32_t length,
uint8_t keep_channel)
{
int i,ii,j,l;
struct complex rx_tmp,tx;
double path_loss = pow(10,desc->path_loss_dB/20);
int dd;
dd = abs(desc->channel_offset);
#ifdef DEBUG_CH
printf("[CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d \n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length);
#endif
if (keep_channel) {
// do nothing - keep channel
} else {
random_channel(desc,0);
}
#ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
}
printf("\n");
#endif
for (i=0; i<((int)length-dd); i++) {
for (ii=0; ii<desc->nb_rx; ii++) {
rx_tmp.x = 0;
rx_tmp.y = 0;
for (j=0; j<desc->nb_tx; j++) {
for (l = 0; l<(int)desc->channel_length; l++) {
if ((i>=0) && (i-l)>=0) {
tx.x = tx_sig_re[j][i-l];
tx.y = tx_sig_im[j][i-l];
} else {
tx.x =0;
tx.y =0;
}
rx_tmp.x += (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].x) - (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].y);
rx_tmp.y += (tx.y * desc->ch[ii+(j*desc->nb_rx)][l].x) + (tx.x * desc->ch[ii+(j*desc->nb_rx)][l].y);
} //l
} // j
rx_sig_re[ii][i+dd] = rx_tmp.x*path_loss;
rx_sig_im[ii][i+dd] = rx_tmp.y*path_loss;
/*
if ((ii==0)&&((i%32)==0)) {
printf("%p %p %f,%f => %e,%e\n",rx_sig_re[ii],rx_sig_im[ii],rx_tmp.x,rx_tmp.y,rx_sig_re[ii][i-dd],rx_sig_im[ii][i-dd]);
}
*/
//rx_sig_re[ii][i] = sqrt(.5)*(tx_sig_re[0][i] + tx_sig_re[1][i]);
//rx_sig_im[ii][i] = sqrt(.5)*(tx_sig_im[0][i] + tx_sig_im[1][i]);
} // ii
} // i
}
#endif