only cleaning: remove dead code, make static functions, simplify code

This commit is contained in:
Laurent THOMAS
2026-02-16 20:04:29 +01:00
committed by Robert Schmidt
parent 40e61d59a6
commit b6171949cd
8 changed files with 478 additions and 1203 deletions
@@ -549,10 +549,7 @@ void construct_HhH_elements(int *ch0conj_ch0, //00_00
}
}
void squared_matrix_element(int32_t *Hh_h_00,
int32_t *Hh_h_00_sq,
unsigned short nb_rb)
static void squared_matrix_element(int32_t *Hh_h_00, int32_t *Hh_h_00_sq, unsigned short nb_rb)
{
simde__m128i *Hh_h_00_128,*Hh_h_00_sq_128;
File diff suppressed because it is too large Load Diff
@@ -20,253 +20,80 @@ data storage. */
//#define DEBUG_PREPROC
#include "common/utils/utils.h"
void transpose (int N, float complex *A, float complex *Result)
{
// COnputes C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C
int col_opB = N; //number of columns of op(B) and in C
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_B; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = rows_opA;
float complex beta = 0.0+I*0;
int ldc = rows_opA;
int i;
float complex* B;
int ldb = col_opB;
if (transb == CblasNoTrans) {
B = calloc_or_fail(ldb * col_opB, sizeof(float complex));
col_B= col_opB;
}
else {
B = calloc_or_fail(ldb * col_opA, sizeof(float complex));
col_B = col_opA;
}
float complex* C = malloc_or_fail(ldc * col_opB * sizeof(float complex));
for (i=0; i<lda*col_B; i+=N+1)
B[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc);
memcpy(Result, C, N*N*sizeof(float complex));
free(B);
free(C);
}
void conjugate_transpose (int N, float complex *A, float complex *Result)
static void conjugate_transpose(int N, float complex* A, float complex* Result)
{
// Computes C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasConjTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C
int col_opB = N; //number of columns of op(B) and in C
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_B; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = rows_opA;
float complex alpha = 1.0 + I * 0;
float complex beta = 0.0+I*0;
int ldc = rows_opA;
int i;
float complex* B;
int ldb = col_opB;
if (transb == CblasNoTrans) {
B = calloc_or_fail(ldb * col_opB, sizeof(float complex));
col_B= col_opB;
}
else {
B = calloc_or_fail(ldb * col_opA, sizeof(float complex));
col_B = col_opA;
}
float complex* C = malloc_or_fail(ldc * col_opB * sizeof(float complex));
for (i=0; i<lda*col_B; i+=N+1)
B[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, B, ldb, &beta, C, ldc);
memcpy(Result, C, N*N*sizeof(float complex));
free(B);
free(C);
}
void H_hermH_plus_sigma2I (int N, int M, float complex *A, float sigma2, float complex *Result)
{
//C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasConjTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = N; // number of rows in op(A) and in C
int col_opB = N; //number of columns of op(B) and in C
int col_opA = N; //number of columns in op(A) and rows in op(B)
int col_C = N; //number of columns in B
float complex alpha = 1.0+I*0;
int lda = col_opA;
float complex beta = 1.0 + I*0;
int ldc = col_opA;
int i;
float complex* C = calloc_or_fail(ldc * col_opB, sizeof(float complex));
for (i=0; i<lda*col_C; i+=N+1)
C[i]=sigma2*(1.0+I*0);
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, A, lda, A, lda, &beta, C, ldc);
memcpy(Result, C, N*M*sizeof(float complex));
free(C);
}
void HH_herm_plus_sigma2I (int M, int N, float complex *A, float sigma2, float complex *Result)
{
//C := alpha*op(A)*op(B) + beta*C,
CBLAS_TRANSPOSE transa = CblasNoTrans;
CBLAS_TRANSPOSE transb = CblasConjTrans;
int k = N; //number of columns in op(A) and rows in op(B),k
float complex alpha = 1.0+I*0;
int lda = N;
int ldb = N;
int ldc = M;
int i;
float complex* C = calloc_or_fail(M * M, sizeof(float complex));
for (i=0; i<M*M; i+=M+1)
C[i]=1.0+I*0;
cblas_cgemm(CblasRowMajor, transa, transb, M, M, k, &alpha, A, lda, A, ldb, &sigma2, C, ldc);
memcpy(Result, C, M*M*sizeof(float complex));
free(C);
float complex B[N][N];
for (int i = 0; i < N; i++)
B[i][i] = 1.0 + I * 0;
cblas_cgemm(CblasRowMajor, CblasConjTrans, CblasNoTrans, N, N, N, &alpha, A, N, B, N, &beta, Result, N);
}
void eigen_vectors_values (int N, float complex *A, float complex *Vectors, float *Values_Matrix)
static void H_hermH_plus_sigma2I(int N, float complex* A, float sigma2, float complex Result[N][N])
{
// This function computes ORTHONORMAL eigenvectors and eigenvalues of matrix A,
// where Values_Matrix is a diagonal matrix of eigenvalues.
// A=Vectors*Values_Matrix*Vectors'
char jobz = 'V';
char uplo = 'U';
int order_A = N;
int lda = N;
int i;
float* Values = malloc_or_fail(sizeof(float) * 1 * N);
LAPACKE_cheev(LAPACK_ROW_MAJOR, jobz, uplo, order_A, A, lda, Values);
memcpy(Vectors, A, N*N*sizeof(float complex));
for (i=0; i<lda; i+=1)
Values_Matrix[i*(lda+1)]=Values[i];
free(Values);
// C := alpha*op(A)*op(B) + beta*C,
float complex alpha = 1.0 + I * 0;
float complex beta = 1.0 + I * 0;
for (int i = 0; i < N; i++)
Result[i][i] = sigma2 * (1.0 + I * 0);
cblas_cgemm(CblasRowMajor, CblasConjTrans, CblasNoTrans, N, N, N, &alpha, A, N, A, N, &beta, Result, N);
}
void lin_eq_solver (int N, float complex* A, float complex* B, float complex* Result)
static void lin_eq_solver(int N, float complex* A, float complex* B, float complex* Result)
{
int n = N;
int lda = N;
int ldb = N;
int nrhs = N;
char transa = 'N';
int* IPIV = malloc_or_fail(N * N * sizeof(int));
int IPIV[N][N];
// Compute LU-factorization
LAPACKE_cgetrf(LAPACK_ROW_MAJOR, n, nrhs, A, lda, IPIV);
LAPACKE_cgetrf(LAPACK_ROW_MAJOR, N, N, A, N, (int*)IPIV);
// Solve AX=B
LAPACKE_cgetrs(LAPACK_ROW_MAJOR, transa, n, nrhs, A, lda, IPIV, B, ldb);
LAPACKE_cgetrs(LAPACK_ROW_MAJOR, 'N', N, N, A, N, (int*)IPIV, B, N);
// cgetrs( "N", N, 4, A, lda, IPIV, B, ldb, INFO )
memcpy(Result, B, N*N*sizeof(float complex));
free(IPIV);
memcpy(Result, B, N * N * sizeof(float complex));
}
void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){
CBLAS_TRANSPOSE transa = CblasNoTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = rows_M0; // number of rows in op(A) and in C
int col_opB = col_M1; //number of columns of op(B) and in C
int col_opA = col_M0; //number of columns in op(A) and rows in op(B)
float complex alpha =1.0;
int lda = col_M0;
void mutl_matrix_matrix_col_based(float complex* M0,
float complex* M1,
int rows_M0,
int col_M0,
int rows_M1,
int col_M1,
float complex* Result)
{
float complex alpha = 1.0;
float complex beta = 0.0;
int ldc = col_M1;
int ldb = col_M1;
cblas_cgemm(CblasColMajor,
CblasNoTrans,
CblasNoTrans,
rows_M0,
col_M1,
col_M0,
&alpha,
M0,
col_M0,
M1,
rows_M1,
&beta,
Result,
rows_M1);
#ifdef DEBUG_PREPROC
int i=0;
printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1);
for(i=0; i<rows_M0*col_M0; ++i)
printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i=0; i<rows_M1*col_M1; ++i)
printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif
cblas_cgemm(CblasRowMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc);
#ifdef DEBUG_PREPROC
for(i=0; i<rows_opA*col_opB; ++i)
printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif
}
void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result ){
CBLAS_TRANSPOSE transa = CblasNoTrans;
CBLAS_TRANSPOSE transb = CblasNoTrans;
int rows_opA = rows_M0; // number of rows in op(A) and in C
int col_opB = col_M1; //number of columns of op(B) and in C
int col_opA = col_M0; //number of columns in op(A) and rows in op(B)
float complex alpha =1.0;
int lda = col_M0;
float complex beta = 0.0;
int ldc = rows_M1;
int ldb = rows_M1;
#ifdef DEBUG_PREPROC
int i = 0;
printf("rows_M0 %d, col_M0 %d, rows_M1 %d, col_M1 %d\n", rows_M0, col_M0, rows_M1, col_M1);
for(i=0; i<rows_M0*col_M0; ++i)
printf(" rows_opA = %d, col_opB = %d, W_MMSE[%d] = (%f + i%f)\n", rows_opA, col_opB, i , creal(M0[i]), cimag(M0[i]));
for(i=0; i<rows_M1*col_M1; ++i)
printf(" M1[%d] = (%f + i%f)\n", i , creal(M1[i]), cimag(M1[i]));
#endif
cblas_cgemm(CblasColMajor, transa, transb, rows_opA, col_opB, col_opA, &alpha, M0, lda, M1, ldb, &beta, Result, ldc);
#ifdef DEBUG_PREPROC
for(i=0; i<rows_opA*col_opB; ++i)
for (i = 0; i < rows_M0 * col_M1; ++i)
printf(" result[%d] = (%f + i%f)\n", i , creal(Result[i]), cimag(Result[i]));
#endif
}
/*FILTERS */
void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE)
{
int N = order_H;
float complex* H_hermH_sigmaI = malloc_or_fail(N * N * sizeof(float complex));
float complex* H_herm = malloc_or_fail(N * N * sizeof(float complex));
H_hermH_plus_sigma2I(N, N, H, sigma2, H_hermH_sigmaI);
float complex H_hermH_sigmaI[N][N];
memset(H_hermH_sigmaI, 0, sizeof(H_hermH_sigmaI));
H_hermH_plus_sigma2I(N, H, sigma2, H_hermH_sigmaI);
#ifdef DEBUG_PREPROC
int i =0;
@@ -274,97 +101,19 @@ void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_
printf(" H_hermH_sigmaI[%d] = (%f + i%f)\n", i , creal(H_hermH_sigmaI[i]), cimag(H_hermH_sigmaI[i]));
#endif
conjugate_transpose (N, H, H_herm); //equals H_herm
float complex H_herm[N][N];
memset(H_herm, 0, sizeof(H_herm));
conjugate_transpose(N, H, (float complex*)H_herm); // equals H_herm
#ifdef DEBUG_PREPROC
for(i=0;i<N*N;i++)
printf(" H_herm[%d] = (%f + i%f)\n", i , creal(H_herm[i]), cimag(H_herm[i]));
#endif
lin_eq_solver(N, H_hermH_sigmaI, H_herm, W_MMSE);
lin_eq_solver(N, (float complex*)H_hermH_sigmaI, (float complex*)H_herm, W_MMSE);
#ifdef DEBUG_PREPROC
for(i=0;i<N*N;i++)
printf(" W_MMSE[%d] = (%f + i%f)\n", i , creal(W_MMSE[i]), cimag(W_MMSE[i]));
#endif
free(H_hermH_sigmaI);
free(H_herm);
}
#if 0
void compute_white_filter(float complex* H_re,
int order_H,
float sigma2,
float complex* W_Wh_0_re,
float complex* W_Wh_1_re){
int aatx, aarx, re;
int i,j;
int M =n_rx;
int N = n_tx;
int sigma2=noise_power;
float complex *H0_re = malloc_or_fail(n_rx*(n_tx>>2)*sizeof(float complex));
float complex *H1_re = malloc_or_fail(n_rx*(n_tx>>2)*sizeof(float complex));
float complex *R_corr_col_n_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *R_corr_col_n_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_0_herm_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *U_1_herm_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *D_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *D_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *W_Wh_0_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
float complex *W_Wh_1_re = malloc_or_fail(n_rx*n_tx*sizeof(float complex));
for (aatx=0; aatx<n_tx/2; aatx++){
for (aarx=0; aarx<n_rx; aarx++) {
H0_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx][re]; // H0 gets [0 1 2 3; 4,5,6,7].' coefficients of H
H1_re[aatx*n_rx + aarx] = H_re[aatx*n_rx + aarx + 8][re]; // H1 gets [8 9 10 11; 12, 13, 14, 15].' coefficients of H
if (re == 0)
printf("ant %d, H_re = (%f + i%f) \n", aatx*n_rx + aarx, creal(H[aatx*n_rx + aarx][re]), cimag(H[aatx*n_rx + aarx][re]));
}
}
//HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H1_re, sigma2, R_corr_col_n_0_re);
HH_herm_plus_sigma2I(n_rx, (n_tx>>2), H0_re, sigma2, R_corr_col_n_1_re);
eigen_vectors_values(n_rx, R_corr_col_n_0_re, U_0_re, D_0_re);
eigen_vectors_values(n_rx, R_corr_col_n_1_re, U_1_re, D_1_re);
transpose (n_rx, U_0_re, U_0_herm_re);
transpose (n_rx, U_1_re, U_1_herm_re);
sigma = (float)(sqrt((double)(sigma2)));
/*The inverse of a diagonal matrix is obtained by replacing each element in the diagonal with its reciprocal.
A square root of a diagonal matrix is given by the diagonal matrix, whose diagonal entries are just the square
roots of the original matrix.*/
D_0_re_inv_sqrt[0] = sqrt_float(1/D_0_re_inv[0]);
D_0_re_inv_sqrt[5] = sqrt_float(1/D_0_re_inv[5]);
D_0_re_inv_sqrt[10] = sqrt_float(1/D_0_re_inv[10]);
D_0_re_inv_sqrt[15] = sqrt_float(1/D_0_re_inv[15]);
D_1_re_inv[0] = sqrt_float(1/D_1_re_inv[0]);
D_1_re_inv[5] = sqrt_float(1/D_1_re_inv[5]);
D_1_re_inv[10] = sqrt_float(1/D_1_re_inv[10]);
D_1_re_inv[15] = sqrt_float(1/D_1_re_inv[15]);
now only to multiply
free(H0);
free(H1);
free(R_corr_col_n_0);
free(R_corr_col_n_1);
}
#endif
float sqrt_float(float x, float sqrt_x)
{
sqrt_x = (float)(sqrt((double)(x)));
return sqrt_x;
}
@@ -5,117 +5,8 @@
#include <stdlib.h>
#include "PHY/defs_UE.h"
/* FUNCTIONS FOR LINEAR PREPROCESSING: MMSE, WHITENNING, etc*/
void transpose(int N, float complex *A, float complex *Result);
void conjugate_transpose(int N, float complex *A, float complex *Result);
void H_hermH_plus_sigma2I(int N, int M, float complex *A, float sigma2, float complex *Result);
void HH_herm_plus_sigma2I(int M, int N, float complex *A, float sigma2, float complex *Result);
void eigen_vectors_values(int N, float complex *A, float complex *Vectors, float *Values_Matrix);
void lin_eq_solver(int N, float complex *A, float complex* B);
//float complex* lin_eq_solver (int N, float complex* A, float complex* B);
/* mutl_matrix_matrix_row_based performs multiplications when matrix is row-oriented H[0], H[1]; H[2], H[3]*/
void mutl_matrix_matrix_row_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result );
/* mutl_matrix_matrix_col_based performs multiplications matrix is column-oriented H[0], H[2]; H[1], H[3]*/
void mutl_matrix_matrix_col_based(float complex* M0, float complex* M1, int rows_M0, int col_M0, int rows_M1, int col_M1, float complex* Result );
void compute_MMSE(float complex* H, int order_H, float sigma2, float complex* W_MMSE);
void compute_white_filter(float complex* H, int order_H, float sigma2, float complex* U_1, float complex* D_1);
void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars,
LTE_DL_FRAME_PARMS *frame_parms,
PHY_MEASUREMENTS *measurements,
unsigned char first_symbol_flag,
MIMO_mode_t mimo_mode,
unsigned short mmse_flag,
int noise_power,
unsigned char symbol,
unsigned short nb_rb);
void precode_channel_est(int32_t **dl_ch_estimates_ext,
LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *pdsch_vars,
unsigned char symbol,
unsigned short nb_rb,
MIMO_mode_t mimo_mode);
void rxdataF_to_float(int32_t **rxdataF_ext,
float complex **rxdataF_f,
int n_rx,
int length,
int start_point);
void chan_est_to_float(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void float_to_chan_est(int32_t **dl_ch_estimates_ext,
float complex **dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void float_to_rxdataF(int32_t **rxdataF_ext,
float complex **rxdataF_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mult_mmse_rxdataF(float complex** Wmmse,
float complex** rxdataF_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mult_mmse_chan_est(float complex** Wmmse,
float complex** dl_ch_estimates_ext_f,
int n_tx,
int n_rx,
int length,
int start_point);
void mmse_processing_core(int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
int sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx,
float complex **H,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
float sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
void whitening_processing_core_flp(float complex** rxdataF_ext_flcpx,
float complex **H,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
float sigma2,
int n_tx,
int n_rx,
int length,
int start_point);
float sqrt_float(float x, float sqrt_x);
-43
View File
@@ -50,49 +50,6 @@
#define MBSFN_FDD_SF7 0x08
#define MBSFN_FDD_SF8 0x04
void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe) {
char fname[32],vname[32];
#define NSYMB_PMCH 12
sprintf(fname,"mch_rxF_ext0.m");
sprintf(vname,"pmch_rxF_ext0");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],12*(ue->frame_parms.N_RB_DL)*12,1,1);
sprintf(fname,"mch_ch_ext00.m");
sprintf(vname,"pmch_ch_ext00");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
/*
LOG_M("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_rho.m","dl_rho",pdsch_vars[eNB_id]->rho[0],12*N_RB_DL*NSYMB_PMCH,1,1);
*/
sprintf(fname,"mch_rxF_comp0.m");
sprintf(vname,"pmch_rxF_comp0");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
sprintf(fname,"mch_rxF_llr.m");
sprintf(vname,"pmch_llr");
LOG_M(fname,vname, ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->llr[0],coded_bits_per_codeword,1,0);
sprintf(fname,"mch_mag1.m");
sprintf(vname,"pmch_mag1");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
sprintf(fname,"mch_mag2.m");
sprintf(vname,"pmch_mag2");
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M("mch00_ch0.m","pmch00_ch0",
&(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
ue->frame_parms.ofdm_symbol_size*12,1,1);
LOG_M("rxsig_mch.m","rxs_mch",
&ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],
ue->frame_parms.samples_per_tti,1,1);
/*
if (PHY_vars_eNB_g)
LOG_M("txsig_mch.m","txs_mch",
&PHY_vars_eNB_g[0][0]->common_vars.txdata[0][0][subframe*ue->frame_parms.samples_per_tti],
ue->frame_parms.samples_per_tti,1,1);*/
}
void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) {
LTE_UE_DLSCH_t *dlsch = ue->dlsch_MCH[eNB_id];
LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
@@ -78,17 +78,6 @@ int rx_pmch_khz_1dot25(PHY_VARS_UE *ue,
unsigned char symbol*/
,int mcs);
/** \brief Dump OCTAVE/MATLAB files for PMCH debugging
@param phy_vars_ue Pointer to UE variables
@param eNB_id index of eNB in ue variables
@param coded_bits_per_codeword G from 36.211
@param subframe Index of subframe
@returns 0 on success
*/
void dump_mch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int subframe);
/** \brief This function computes the LLRs for ML (max-logsum approximation) dual-stream QPSK/QPSK reception.
@param stream0_in Input from channel compensated (MR combined) stream 0
@param stream1_in Input from channel compensated (MR combined) stream 1
@@ -580,216 +569,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
uint32_t llr_offset,
uint8_t beamforming_mode);
/** \fn dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
uint8_t l,
uint16_t nb_rb)
\brief This function does the first stage of llr computation for SISO, by just extracting the pilots, PBCH and primary/secondary synchronization sequences.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param rxdataF_comp_i Compensated channel output for interference
@param l symbol in sub-frame
@param nb_rb Number of RBs in this allocation
*/
void dlsch_siso(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
uint8_t l,
uint16_t nb_rb);
/** \fn dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb)
\brief This function does Alamouti combining on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param symbol Symbol in sub-frame
@param nb_rb Number of RBs in this allocation
*/
void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb);
/** \fn dlsch_antcyc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb)
\brief This function does antenna selection (based on antenna cycling pattern) on RX and prepares LLR inputs by skipping pilots, PBCH and primary/secondary synchronization signals. Note that this is not LTE, it is just included for comparison purposes.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param symbol Symbol in sub-frame
@param nb_rb Number of RBs in this allocation
*/
void dlsch_antcyc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb);
/** \fn dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
int32_t **rho,
int32_t **rho_i,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
uint8_t symbol,
uint16_t nb_rb,
uint8_t dual_stream_UE)
\brief This function does maximal-ratio combining for dual-antenna receivers.
@param frame_parms Frame descriptor structure
@param rxdataF_comp Compensated channel output
@param rxdataF_comp_i Compensated channel output for interference
@param rho Cross correlation between spatial channels
@param rho_i Cross correlation between signal and inteference channels
@param dl_ch_mag First squared-magnitude of channel (16QAM and 64QAM) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param dl_ch_magb Second squared-magnitude of channel (64QAM only) for LLR computation. Alamouti combining should be performed on this as well. Result is stored in first antenna position
@param symbol Symbol in sub-frame
@param nb_rb Number of RBs in this allocation
@param dual_stream_UE Flag to indicate dual-stream detection
*/
void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int32_t **rxdataF_comp_i,
int32_t **rho,
int32_t **rho_i,
int32_t **dl_ch_mag,
int32_t **dl_ch_magb,
int32_t **dl_ch_mag_i,
int32_t **dl_ch_magb_i,
uint8_t symbol,
uint16_t nb_rb,
uint8_t dual_stream_UE);
void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *lte_ue_pdsch_vars,
int harq_pid,
int round,
unsigned char symbol,
unsigned short nb_rb,
unsigned char dual_stream_UE);
/** \fn dlsch_extract_rbs_single(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
LTE_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for single antenna eNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_ch_estimates Channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
@param pmi subband Precoding matrix indicator
@param pmi_ext Extracted PMI for chosen RBs
@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
*/
uint16_t dlsch_extract_rbs_single(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
/** \fn dlsch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
LTE_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for dual antenna eNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_ch_estimates Channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_ch_estimates_ext Channel estimates for RBs in this allocation
@param pmi subband Precoding matrix indicator
@param pmi_ext Extracted PMI for chosen RBs
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param subframe Subframe index
@param high_speed_flag
@param frame_parms Pointer to frame descriptor
*/
uint16_t dlsch_extract_rbs_dual(int32_t **rxdataF,
int32_t **dl_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_ch_estimates_ext,
uint16_t pmi,
uint8_t *pmi_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms,
MIMO_mode_t mimo_mode);
/** \fn dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_bf_ch_estimates_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms)
\brief This function extracts the received resource blocks, both channel estimates and data symbols,
for the current allocation and for single antenna eNB transmission.
@param rxdataF Raw FFT output of received signal
@param dl_bf_ch_estimates Beamforming channel estimates of current slot
@param rxdataF_ext FFT output for RBs in this allocation
@param dl_bf_ch_estimates_ext Beamforming channel estimates for RBs in this allocation
@param rb_alloc RB allocation vector
@param symbol Symbol to extract
@param subframe Subframe number
@param high_speed_flag
@param frame_parms Pointer to frame descriptor
*/
uint16_t dlsch_extract_rbs_TM7(int32_t **rxdataF,
int32_t **dl_bf_ch_estimates,
int32_t **rxdataF_ext,
int32_t **dl_bf_ch_estimates_ext,
uint32_t *rb_alloc,
uint8_t symbol,
uint8_t subframe,
uint32_t high_speed_flag,
LTE_DL_FRAME_PARMS *frame_parms);
/** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
@param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
@param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
@@ -819,35 +598,6 @@ void dlsch_channel_compensation(int32_t **rxdataF_ext,
uint8_t output_shift,
PHY_MEASUREMENTS *phy_measurements);
void dlsch_channel_compensation_core(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
int **rho,
unsigned char n_tx,
unsigned char n_rx,
unsigned char mod_order,
unsigned char output_shift,
int length,
int start_point);
void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
unsigned short nb_rb,
int **dl_ch_estimates_ext,
int **dl_ch_estimates_ext_i,
int **dl_ch_rho_ext,
unsigned char output_shift);
void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
unsigned short nb_rb,
int **dl_ch_estimates_ext,
int **dl_ch_estimates_ext_i,
int **dl_ch_rho_ext,
unsigned char output_shift0,
unsigned char output_shift1);
//This function is used to compute multiplications in Hhermitian * H matrix
void conjch0_mult_ch1(int *ch0,
int *ch1,
@@ -869,10 +619,6 @@ void construct_HhH_elements(int *ch0conj_ch0,
int32_t *after_mf_11,
unsigned short nb_rb);
void squared_matrix_element(int32_t *Hh_h_00,
int32_t *Hh_h_00_sq,
unsigned short nb_rb);
void dlsch_channel_level_TM34_meas(int *ch00,
int *ch01,
int *ch10,
@@ -901,38 +647,6 @@ uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
int *dl_ch_estimates_11,
unsigned short nb_rb);
void dlsch_channel_compensation_TM56(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
unsigned char *pmi_ext,
LTE_DL_FRAME_PARMS *frame_parms,
PHY_MEASUREMENTS *phy_measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order,
unsigned short nb_rb,
unsigned char output_shift,
unsigned char dl_power_off);
void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_PDSCH *lte_ue_pdsch_vars,
PHY_MEASUREMENTS *phy_measurements,
int eNB_id,
unsigned char symbol,
unsigned char mod_order0,
unsigned char mod_order1,
int harq_pid,
int round,
MIMO_mode_t mimo_mode,
unsigned short nb_rb,
unsigned short mmse_flag,
unsigned char output_shift0,
unsigned char output_shift1);
/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
@param dl_ch_estimates_ext Channel estimates in allocated RBs
@param frame_parms Pointer to frame descriptor
@@ -1669,12 +1383,6 @@ uint8_t is_not_pilot(uint8_t pilots, uint8_t re, uint8_t nushift, uint8_t use2nd
uint8_t is_not_UEspecRS(int8_t lprime, uint8_t re, uint8_t nushift, uint8_t Ncp, uint8_t beamforming_mode);
uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB,
LTE_DL_FRAME_PARMS *lte_frame_parms,
LTE_UE_DLSCH_t *dlsch,
uint8_t subframe,
uint8_t num_pdcch_symbols);
// DL power control functions
double get_pa_dB(uint8_t pa);
@@ -50,30 +50,6 @@
//#define DEBUG_DLSCH_DEMOD
//#define DEBUG_PDSCH_RX
// [MCS][i_mod (0,1,2) = (2,4,6)]
//unsigned char offset_mumimo_llr_drange_fix=0;
//inferference-free case
/*unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;*/
//unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1,
// 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous
/*
unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{6,6,6},{6,6,6},{6,6,6},{5,5,5},{4,4,4},{1,2,4}, // QPSK
{5,5,4},{5,5,5},{5,5,5},{3,3,3},{2,2,2},{2,2,2},{2,2,2}, // 16-QAM
{2,2,1},{3,3,3},{3,3,3},{3,3,1},{2,2,2},{2,2,2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; //64-QAM
*/
/*
//first optimization try
unsigned char offset_mumimo_llr_drange[29][3]={{7, 8, 7},{6, 6, 7},{6, 6, 7},{6, 6, 6},{5, 6, 6},{5, 5, 6},{5, 5, 6},{4, 5, 4},{4, 3, 4},{3, 2, 2},{6, 5, 5},{5, 4, 4},{5, 5, 4},{3, 3, 2},{2, 2, 1},{2, 1, 1},{2, 2, 2},{3, 3, 3},{3, 3, 2},{3, 3, 2},{3, 2, 1},{2, 2, 2},{2, 2, 2},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
*/
//second optimization try
/*
unsigned char offset_mumimo_llr_drange[29][3]={{5, 8, 7},{4, 6, 8},{3, 6, 7},{7, 7, 6},{4, 7, 8},{4, 7, 4},{6, 6, 6},{3, 6, 6},{3, 6, 6},{1, 3, 4},{1, 1, 0},{3, 3, 2},{3, 4, 1},{4, 0, 1},{4, 2, 2},{3, 1, 2},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; w
*/
//unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}};
#define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3])
#define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
+7 -12
View File
@@ -2925,19 +2925,16 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
else
ue->dlsch_mtch_errors[sync_area][0]++;
LOG_E(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
LOG_E(PHY,
"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
ue->Mod_id,
frame_rx,subframe_rx,
frame_rx,
subframe_rx,
ue->dlsch_mcch_errors[sync_area][0],
ue->dlsch_mtch_errors[sync_area][0],
ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
ue->dlsch_MCH[0]->harq_processes[0]->TBS >> 3,
ue->dlsch_MCH[0]->max_turbo_iterations,
ue->dlsch_MCH[0]->harq_processes[0]->G);
// dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
//if(subframe_rx == 3){
//dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
//exit_fun("nothing to add");
//}
if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) {
for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
@@ -2962,11 +2959,9 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
CC_id,
frame_rx,
ue->dlsch_MCH[0]->harq_processes[0]->b,
ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
eNB_id,// not relevant in eMBMS context
ue->dlsch_MCH[0]->harq_processes[0]->TBS >> 3,
eNB_id, // not relevant in eMBMS context
sync_area);
//dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
//exit_fun("nothing to add");
if (mcch_active == 1)
ue->dlsch_mcch_received[sync_area][0]++;