Feat: improve layer mapping by 32 bits assignment
This commit is contained in:
committed by
francescomani
parent
c5aeaf03dc
commit
b240bc485f
@@ -241,71 +241,74 @@ void nr_modulation(uint32_t *in,
|
||||
AssertFatal(false,"Invalid or unsupported modulation order %d\n",mod_order);
|
||||
}
|
||||
|
||||
void nr_layer_mapping(int16_t **mod_symbs,
|
||||
void nr_layer_mapping(int nbCodes,
|
||||
int encoded_len,
|
||||
c16_t mod_symbs[nbCodes][encoded_len],
|
||||
uint8_t n_layers,
|
||||
int layerSz,
|
||||
uint32_t n_symbs,
|
||||
int16_t **tx_layers)
|
||||
c16_t tx_layers[n_layers][layerSz])
|
||||
{
|
||||
LOG_D(PHY,"Doing layer mapping for %d layers, %d symbols\n",n_layers,n_symbs);
|
||||
|
||||
switch (n_layers) {
|
||||
|
||||
case 1:
|
||||
memcpy((void*)tx_layers[0], (void*)mod_symbs[0], (n_symbs<<1)*sizeof(int16_t));
|
||||
break;
|
||||
memcpy(tx_layers[0], mod_symbs[0], n_symbs * sizeof(**mod_symbs));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
for (int i=0; i<n_symbs/n_layers; i++)
|
||||
for (int l=0; l<n_layers; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[0][(n_layers*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[0][((n_layers*i+l)<<1)+1];
|
||||
}
|
||||
for (int i = 0; i < n_symbs / n_layers; i++) {
|
||||
const c16_t *base = mod_symbs[0] + n_layers * i;
|
||||
for (int l = 0; l < n_layers; l++)
|
||||
tx_layers[l][i] = base[l];
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
for (int i=0; i<n_symbs>>1; i++)
|
||||
for (int l=0; l<2; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[0][((i<<1)+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<1)+l)<<1)+1];
|
||||
}
|
||||
for (int i=0; i<n_symbs/3; i++)
|
||||
for (int l=2; l<5; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
|
||||
}
|
||||
for (int i = 0; i < n_symbs; i += 2) {
|
||||
const int txIdx = i / 2;
|
||||
for (int l = 0; l < 2; l++)
|
||||
tx_layers[l][txIdx] = mod_symbs[0][i + l];
|
||||
}
|
||||
for (int i = 0; i < n_symbs; i += 3) {
|
||||
const int txIdx = i / 3;
|
||||
for (int l = 2; l < 5; l++)
|
||||
tx_layers[l][txIdx] = mod_symbs[1][i + l];
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
for (int q=0; q<2; q++)
|
||||
for (int i=0; i<n_symbs/3; i++)
|
||||
for (int l=0; l<3; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1];
|
||||
}
|
||||
for (int i = 0; i < n_symbs; i += 3) {
|
||||
const int txIdx = i / 3;
|
||||
for (int l = 0; l < 3; l++)
|
||||
tx_layers[l][txIdx] = mod_symbs[q][i + l];
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
for (int i=0; i<n_symbs/3; i++)
|
||||
for (int l=0; l<3; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
|
||||
}
|
||||
for (int i=0; i<n_symbs/4; i++)
|
||||
for (int l=3; l<7; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[0][((i<<2)+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<2)+l)<<1)+1];
|
||||
}
|
||||
for (int i = 0; i < n_symbs; i += 3) {
|
||||
const int txIdx = i / 3;
|
||||
for (int l = 0; l < 3; l++)
|
||||
tx_layers[l][txIdx] = mod_symbs[1][i + l];
|
||||
}
|
||||
for (int i = 0; i < n_symbs; i += 4) {
|
||||
const int txIdx = i / 4;
|
||||
for (int l = 3; l < 7; l++)
|
||||
tx_layers[l][txIdx] = mod_symbs[0][i + l];
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
for (int q=0; q<2; q++)
|
||||
for (int i=0; i<n_symbs>>2; i++)
|
||||
for (int l=0; l<3; l++) {
|
||||
tx_layers[l][i<<1] = mod_symbs[q][((i<<2)+l)<<1];
|
||||
tx_layers[l][(i<<1)+1] = mod_symbs[q][(((i<<2)+l)<<1)+1];
|
||||
}
|
||||
for (int i = 0; i < n_symbs; i += 4) {
|
||||
const int txIdx = i / 4;
|
||||
for (int l = 0; l < 3; l++)
|
||||
tx_layers[l][txIdx] = mod_symbs[q][i + l];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -694,17 +697,17 @@ int nr_layer_precoder(int16_t **datatx_F_precoding, const char *prec_matrix, uin
|
||||
((int16_t *)precodatatx_F)[1] = (int16_t)((((int16_t *)precodatatx_F)[1]*ONE_OVER_SQRT2_Q15)>>15);*/
|
||||
}
|
||||
|
||||
int nr_layer_precoder_cm(int16_t **datatx_F_precoding, int *prec_matrix, uint8_t n_layers, int32_t re_offset)
|
||||
c16_t nr_layer_precoder_cm(int n_layers,
|
||||
int n_symbols,
|
||||
int symSz,
|
||||
c16_t datatx_F_precoding[n_layers][n_symbols][symSz],
|
||||
c16_t *prec_matrix,
|
||||
int symbol,
|
||||
int offset)
|
||||
{
|
||||
int32_t precodatatx_F = 0;
|
||||
for (int al = 0; al<n_layers; al++) {
|
||||
int16_t antenna_re = datatx_F_precoding[al][re_offset<<1];
|
||||
int16_t antenna_im = datatx_F_precoding[al][(re_offset<<1) +1];
|
||||
//printf("antenna precoding: %d %d\n",((int16_t *)&prec_matrix[al])[0],((int16_t *)&prec_matrix[al])[1]);
|
||||
((int16_t *) &precodatatx_F)[0] += (int16_t)(((int32_t)(antenna_re*(((int16_t *)&prec_matrix[al])[0])) - (int32_t)(antenna_im* (((int16_t *)&prec_matrix[al])[1])))>>15);
|
||||
((int16_t *) &precodatatx_F)[1] += (int16_t)(((int32_t)(antenna_re*(((int16_t *)&prec_matrix[al])[1])) + (int32_t)(antenna_im* (((int16_t *)&prec_matrix[al])[0])))>>15);
|
||||
}
|
||||
|
||||
c16_t precodatatx_F = {0};
|
||||
for (int al = 0; al < n_layers; al++)
|
||||
precodatatx_F = c16maddShift(datatx_F_precoding[al][symbol][offset], prec_matrix[al], precodatatx_F, 15);
|
||||
return precodatatx_F;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,10 +54,13 @@ void nr_modulation(uint32_t *in,
|
||||
@param[out] tx_layers, modulated symbols for each layer
|
||||
*/
|
||||
|
||||
void nr_layer_mapping(int16_t **mod_symbs,
|
||||
uint8_t n_layers,
|
||||
uint32_t n_symbs,
|
||||
int16_t **tx_layers);
|
||||
void nr_layer_mapping(int nbCodes,
|
||||
int encoded_len,
|
||||
c16_t mod_symbs[nbCodes][encoded_len],
|
||||
uint8_t n_layers,
|
||||
int layerSz,
|
||||
uint32_t n_symbs,
|
||||
c16_t tx_layers[n_layers][layerSz]);
|
||||
|
||||
/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3
|
||||
@param[in] ulsch_ue, double Pointer to NR_UE_ULSCH_t struct
|
||||
@@ -135,9 +138,11 @@ void apply_nr_rotation_RX(NR_DL_FRAME_PARMS *frame_parms,
|
||||
@param[in] n_layers, number of DLSCH layers
|
||||
*/
|
||||
int nr_layer_precoder(int16_t **datatx_F_precoding, const char *prec_matrix, uint8_t n_layers, int32_t re_offset);
|
||||
|
||||
int nr_layer_precoder_cm(int16_t **datatx_F_precoding,
|
||||
int *prec_matrix,
|
||||
uint8_t n_layers,
|
||||
int32_t re_offset);
|
||||
c16_t nr_layer_precoder_cm(int n_layers,
|
||||
int n_symbols,
|
||||
int symSz,
|
||||
c16_t datatx_F_precoding[n_layers][n_symbols][symSz],
|
||||
c16_t *prec_matrix,
|
||||
int symbol,
|
||||
int offset);
|
||||
#endif
|
||||
|
||||
@@ -53,15 +53,10 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
|
||||
nr_codeword_scrambling(in, size, q, Nid, n_RNTI, out);
|
||||
}
|
||||
|
||||
void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
int frame,
|
||||
int slot) {
|
||||
|
||||
void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
|
||||
{
|
||||
PHY_VARS_gNB *gNB = msgTx->gNB;
|
||||
NR_gNB_DLSCH_t *dlsch;
|
||||
c16_t** txdataF = gNB->common_vars.txdataF;
|
||||
int16_t amp = gNB->TX_AMP;
|
||||
int xOverhead = 0;
|
||||
const int16_t amp = gNB->TX_AMP;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
time_stats_t *dlsch_encoding_stats=&gNB->dlsch_encoding_stats;
|
||||
time_stats_t *dlsch_scrambling_stats=&gNB->dlsch_scrambling_stats;
|
||||
@@ -75,25 +70,17 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats;
|
||||
|
||||
for (int dlsch_id=0; dlsch_id<msgTx->num_pdsch_slot; dlsch_id++) {
|
||||
dlsch = &msgTx->dlsch[dlsch_id][0];
|
||||
NR_gNB_DLSCH_t *dlsch = msgTx->dlsch[dlsch_id];
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
|
||||
int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs;
|
||||
int16_t **tx_layers = (int16_t**)dlsch->txdataF;
|
||||
int8_t Wf[2], Wt[2], l0, l_prime, l_overline, delta;
|
||||
uint8_t dmrs_Type = rel15->dmrsConfigType;
|
||||
int nb_re_dmrs;
|
||||
uint16_t n_dmrs;
|
||||
const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8;
|
||||
c16_t tx_layers[rel15->nrOfLayers][layerSz] __attribute__((aligned(64)));
|
||||
const int dmrs_Type = rel15->dmrsConfigType;
|
||||
const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
|
||||
LOG_D(PHY,"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n",
|
||||
rel15->BWPStart,rel15->BWPSize,rel15->rbStart,rel15->rbSize);
|
||||
if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
|
||||
nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
|
||||
}
|
||||
else {
|
||||
nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
|
||||
}
|
||||
n_dmrs = (rel15->BWPStart+rel15->rbStart+rel15->rbSize)*nb_re_dmrs;
|
||||
const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs;
|
||||
|
||||
if(rel15->dlDmrsScramblingId != gNB->pdsch_gold_init[rel15->SCID]) {
|
||||
gNB->pdsch_gold_init[rel15->SCID] = rel15->dlDmrsScramblingId;
|
||||
@@ -101,16 +88,16 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
}
|
||||
|
||||
uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot];
|
||||
uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
|
||||
uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint32_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
|
||||
uint8_t Qm = rel15->qamModOrder[0];
|
||||
uint32_t encoded_length = nb_re*Qm;
|
||||
int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16)));
|
||||
const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100
|
||||
const int xOverhead = 0;
|
||||
const int nb_re =
|
||||
(12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * rel15->rbSize * rel15->nrOfLayers;
|
||||
const int Qm = rel15->qamModOrder[0];
|
||||
const int encoded_length = nb_re * Qm;
|
||||
|
||||
/* PTRS */
|
||||
uint16_t dlPtrsSymPos = 0;
|
||||
uint16_t n_ptrs = 0;
|
||||
int n_ptrs = 0;
|
||||
uint32_t ptrsSymbPerSlot = 0;
|
||||
if(rel15->pduBitmap & 0x1) {
|
||||
set_ptrs_symb_idx(&dlPtrsSymPos,
|
||||
@@ -125,7 +112,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
|
||||
/// CRC, coding, interleaving and rate matching
|
||||
AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n");
|
||||
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers] __attribute__((aligned(32)));
|
||||
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers] __attribute__((aligned(64)));
|
||||
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers);
|
||||
start_meas(dlsch_encoding_stats);
|
||||
|
||||
@@ -163,18 +150,14 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
if (IS_SOFTMODEM_DLSIM)
|
||||
memcpy(harq->f, output, encoded_length);
|
||||
|
||||
for (int q=0; q<rel15->NrOfCodewords; q++) {
|
||||
c16_t mod_symbs[rel15->NrOfCodewords][encoded_length];
|
||||
for (int codeWord = 0; codeWord < rel15->NrOfCodewords; codeWord++) {
|
||||
/// scrambling
|
||||
start_meas(dlsch_scrambling_stats);
|
||||
uint32_t scrambled_output[(encoded_length>>5)+4]; // modulator acces by 4 bytes in some cases
|
||||
memset(scrambled_output, 0, sizeof(scrambled_output));
|
||||
if ( encoded_length > rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers) abort();
|
||||
nr_pdsch_codeword_scrambling(output,
|
||||
encoded_length,
|
||||
q,
|
||||
rel15->dataScramblingId,
|
||||
rel15->rnti,
|
||||
scrambled_output);
|
||||
nr_pdsch_codeword_scrambling(output, encoded_length, codeWord, rel15->dataScramblingId, rel15->rnti, scrambled_output);
|
||||
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("PDSCH scrambling:\n");
|
||||
@@ -188,36 +171,30 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
stop_meas(dlsch_scrambling_stats);
|
||||
/// Modulation
|
||||
start_meas(dlsch_modulation_stats);
|
||||
nr_modulation(scrambled_output,
|
||||
encoded_length,
|
||||
Qm,
|
||||
mod_symbs[q]);
|
||||
nr_modulation(scrambled_output, encoded_length, Qm, (int16_t *)mod_symbs[codeWord]);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0);
|
||||
stop_meas(dlsch_modulation_stats);
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("PDSCH Modulation: Qm %d(%u)\n", Qm, nb_re);
|
||||
for (int i=0; i<nb_re>>3; i++) {
|
||||
for (int i = 0; i < nb_re; i += 8) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]);
|
||||
printf("%d %d\t", mod_symbs[codeWord][i + j].r, mod_symbs[codeWord][i + j].i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
start_meas(&gNB->dlsch_layer_mapping_stats);
|
||||
/// Layer mapping
|
||||
nr_layer_mapping(mod_symbs,
|
||||
rel15->nrOfLayers,
|
||||
nb_re,
|
||||
tx_layers);
|
||||
nr_layer_mapping(rel15->NrOfCodewords, encoded_length, mod_symbs, rel15->nrOfLayers, layerSz, nb_re, tx_layers);
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("Layer mapping (%d layers):\n", rel15->nrOfLayers);
|
||||
for (int l=0; l<rel15->nrOfLayers; l++)
|
||||
for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) {
|
||||
printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7);
|
||||
for (int i = 0; i < nb_re / rel15->nrOfLayers; i += 8) {
|
||||
printf("layer %d, Re %d..%d : ", l, i, i + 7);
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]);
|
||||
printf("l%d %d\t", tx_layers[l][i + j].r, tx_layers[l][i + j].i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -232,10 +209,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
int txdataF_offset = slot*frame_parms->samples_per_slot_wCP;
|
||||
int16_t **txdataF_precoding = (int16_t **)malloc16(rel15->nrOfLayers*sizeof(int16_t *));
|
||||
for (int layer = 0; layer<rel15->nrOfLayers; layer++)
|
||||
txdataF_precoding[layer] = (int16_t *)malloc16(2*14*frame_parms->ofdm_symbol_size*sizeof(int16_t));
|
||||
const uint32_t txdataF_offset = slot*frame_parms->samples_per_slot_wCP;
|
||||
c16_t txdataF_precoding[rel15->nrOfLayers][NR_NUMBER_OF_SYMBOLS_PER_SLOT][frame_parms->ofdm_symbol_size] __attribute__((aligned(64)));;
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %u,nb_layers %d)\n",
|
||||
@@ -243,63 +218,66 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
#endif
|
||||
|
||||
start_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
for (int nl=0; nl<rel15->nrOfLayers; nl++) {
|
||||
|
||||
int dmrs_port = get_dmrs_port(nl,rel15->dmrsPorts);
|
||||
for (int layer = 0; layer < rel15->nrOfLayers; layer++) {
|
||||
int dmrs_port = get_dmrs_port(layer, rel15->dmrsPorts);
|
||||
|
||||
// DMRS params for this dmrs port
|
||||
int Wt[2], Wf[2];
|
||||
get_Wt(Wt, dmrs_port, dmrs_Type);
|
||||
get_Wf(Wf, dmrs_port, dmrs_Type);
|
||||
delta = get_delta(dmrs_port, dmrs_Type);
|
||||
l_prime = 0; // single symbol nl 0
|
||||
l0 = get_l0(rel15->dlDmrsSymbPos);
|
||||
l_overline = l0;
|
||||
const int8_t delta = get_delta(dmrs_port, dmrs_Type);
|
||||
int8_t l_prime = 0; // single symbol layer 0
|
||||
int8_t l_overline = get_l0(rel15->dlDmrsSymbPos);
|
||||
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
uint8_t dmrs_symbol = l0+l_prime;
|
||||
printf("DMRS Type %d params for nl %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
|
||||
1+dmrs_Type,nl, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol);
|
||||
uint8_t dmrs_symbol = l_overline + l_prime;
|
||||
printf("DMRS Type %d params for layer %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n",
|
||||
1 + dmrs_Type,
|
||||
layer,
|
||||
Wt[0],
|
||||
Wt[1],
|
||||
Wf[0],
|
||||
Wf[1],
|
||||
delta,
|
||||
l_prime,
|
||||
l_overline,
|
||||
dmrs_symbol);
|
||||
#endif
|
||||
|
||||
uint32_t m=0, dmrs_idx=0;
|
||||
AssertFatal(n_dmrs, "n_dmrs can't be 0\n");
|
||||
c16_t mod_dmrs[n_dmrs] __attribute__((aligned(64)));
|
||||
|
||||
// Loop Over OFDM symbols:
|
||||
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
|
||||
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
|
||||
/// DMRS QPSK modulation
|
||||
uint8_t k_prime=0;
|
||||
uint16_t n=0;
|
||||
|
||||
if ((dmrs_symbol_map & (1 << l))){ // DMRS time occasion
|
||||
if ((dmrs_symbol_map & (1 << l_symbol))) { // DMRS time occasion
|
||||
// The reference point for is subcarrier 0 of the lowest-numbered resource block in CORESET 0 if the corresponding
|
||||
// PDCCH is associated with CORESET 0 and Type0-PDCCH common search space and is addressed to SI-RNTI
|
||||
// 3GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources
|
||||
if (rel15->rnti==SI_RNTI) {
|
||||
if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
|
||||
dmrs_idx = rel15->rbStart*6;
|
||||
} else {
|
||||
dmrs_idx = rel15->rbStart*4;
|
||||
}
|
||||
} else {
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) {
|
||||
dmrs_idx = (rel15->rbStart+rel15->BWPStart)*6;
|
||||
} else {
|
||||
dmrs_idx = (rel15->rbStart+rel15->BWPStart)*4;
|
||||
}
|
||||
}
|
||||
if (l==(l_overline+1)) //take into account the double DMRS symbols
|
||||
dmrs_idx = rel15->rbStart;
|
||||
if (rel15->rnti != SI_RNTI)
|
||||
dmrs_idx += rel15->BWPStart;
|
||||
dmrs_idx *= dmrs_Type == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
|
||||
if (l_symbol == (l_overline + 1)) // take into account the double DMRS symbols
|
||||
l_prime = 1;
|
||||
else if (l>(l_overline+1)) {//new DMRS pair
|
||||
l_overline = l;
|
||||
else if (l_symbol > (l_overline + 1)) { // new DMRS pair
|
||||
l_overline = l_symbol;
|
||||
l_prime = 0;
|
||||
}
|
||||
/// DMRS QPSK modulation
|
||||
nr_modulation(pdsch_dmrs[l][rel15->SCID], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
|
||||
nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID],
|
||||
n_dmrs * DMRS_MOD_ORDER,
|
||||
DMRS_MOD_ORDER,
|
||||
(int16_t *)mod_dmrs); // Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_DLSCH
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type);
|
||||
for (int i=0; i<n_dmrs>>4; i++) {
|
||||
printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l_symbol, n_dmrs, dmrs_Type);
|
||||
for (int i = 0; i < n_dmrs / 2; i += 8) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]);
|
||||
printf("%d %d\t", mod_dmrs[i + j].r, mod_dmrs[i + j].i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -307,22 +285,19 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
}
|
||||
|
||||
/* calculate if current symbol is PTRS symbols */
|
||||
uint16_t ptrs_idx = 0;
|
||||
int16_t *mod_ptrs = NULL;
|
||||
uint8_t ptrs_symbol = 0;
|
||||
int ptrs_idx = 0;
|
||||
int ptrs_symbol = 0;
|
||||
c16_t mod_ptrs[max(n_ptrs, 1)] __attribute__((aligned(64))); //max only to please sanitizer, that kills if 0 even if it is not a error
|
||||
if(rel15->pduBitmap & 0x1) {
|
||||
ptrs_symbol = is_ptrs_symbol(l, dlPtrsSymPos);
|
||||
ptrs_symbol = is_ptrs_symbol(l_symbol, dlPtrsSymPos);
|
||||
if(ptrs_symbol) {
|
||||
/* PTRS QPSK Modulation for each OFDM symbol in a slot */
|
||||
LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n", l, n_ptrs);
|
||||
int16_t mod_ptrsBuf[n_ptrs<<1] __attribute__ ((aligned(16)));
|
||||
mod_ptrs = mod_ptrsBuf;
|
||||
nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs << 1), DMRS_MOD_ORDER, mod_ptrs);
|
||||
LOG_D(PHY, "Doing ptrs modulation for symbol %d, n_ptrs %d\n", l_symbol, n_ptrs);
|
||||
nr_modulation(pdsch_dmrs[l_symbol][rel15->SCID], n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
|
||||
}
|
||||
}
|
||||
uint16_t k = start_sc;
|
||||
if (ptrs_symbol || dmrs_symbol_map & (1 << l)) {
|
||||
|
||||
if (ptrs_symbol || dmrs_symbol_map & (1 << l_symbol)) {
|
||||
// Loop Over SCs:
|
||||
for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
|
||||
/* check if cuurent RE is PTRS RE*/
|
||||
@@ -338,14 +313,18 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
frame_parms->ofdm_symbol_size);
|
||||
}
|
||||
/* Map DMRS Symbol */
|
||||
if ( (dmrs_symbol_map & (1 << l)) &&
|
||||
(k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 ] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
|
||||
if ((dmrs_symbol_map & (1 << l_symbol))
|
||||
&& (k == ((start_sc + get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type)) % (frame_parms->ofdm_symbol_size)))) {
|
||||
txdataF_precoding[layer][l_symbol][k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp, 15);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("dmrs_idx %u\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n",
|
||||
dmrs_idx, l, k, k_prime, n, txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1)],
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]);
|
||||
dmrs_idx,
|
||||
l_symbol,
|
||||
k,
|
||||
k_prime,
|
||||
n,
|
||||
txdataF_precoding[layer][l_symbol][k].r,
|
||||
txdataF_precoding[layer][l_symbol][k].i);
|
||||
#endif
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
@@ -353,38 +332,49 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
n+=(k_prime)?0:1;
|
||||
}
|
||||
/* Map PTRS Symbol */
|
||||
else if(is_ptrs_re){
|
||||
else if (is_ptrs_re) {
|
||||
uint16_t beta_ptrs = 1;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
|
||||
txdataF_precoding[layer][l_symbol][k] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * amp, 15);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d, mod_ptrs: %d %d\n",
|
||||
ptrs_idx, l, k, k_prime, n, ((int16_t*)txdataF_precoding[nl])[((l*frame_parms->ofdm_symbol_size + k)<<1)],
|
||||
((int16_t*)txdataF_precoding[nl])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1],mod_ptrs[ptrs_idx<<1],mod_ptrs[(ptrs_idx<<1)+1]);
|
||||
ptrs_idx,
|
||||
l_symbol,
|
||||
k,
|
||||
k_prime,
|
||||
n,
|
||||
txdataF_precoding[layer][l_symbol][k].r,
|
||||
txdataF_precoding[layer][l_symbol][k].i,
|
||||
mod_ptrs[ptrs_idx].r,
|
||||
mod_ptrs[ptrs_idx].i);
|
||||
#endif
|
||||
ptrs_idx++;
|
||||
}
|
||||
/* Map DATA Symbol */
|
||||
else if( ptrs_symbol || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) {
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = (amp * tx_layers[nl][m<<1]) >> 15;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[nl][(m<<1) + 1]) >> 15;
|
||||
/* Map DATA Symbol */
|
||||
else if (ptrs_symbol
|
||||
|| allowed_xlsch_re_in_dmrs_symbol(k,
|
||||
start_sc,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
rel15->numDmrsCdmGrpsNoData,
|
||||
dmrs_Type)) {
|
||||
txdataF_precoding[layer][l_symbol][k] = c16mulRealShift(tx_layers[layer][m], amp, 15);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("m %u\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
m, l, k, txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1)],
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]);
|
||||
m,
|
||||
l_symbol,
|
||||
k,
|
||||
txdataF_precoding[layer][l_symbol][k].r,
|
||||
txdataF_precoding[layer][l_symbol][k].i);
|
||||
#endif
|
||||
m++;
|
||||
}
|
||||
/* mute RE */
|
||||
else {
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
|
||||
txdataF_precoding[layer][l_symbol][k] = (c16_t){0};
|
||||
}
|
||||
if (++k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
} //RE loop
|
||||
}
|
||||
else { // no PTRS or DMRS in this symbol
|
||||
} else { // no PTRS or DMRS in this symbol
|
||||
// Loop Over SCs:
|
||||
int upper_limit=rel15->rbSize*NR_NB_SC_PER_RB;
|
||||
int remaining_re = 0;
|
||||
@@ -393,27 +383,28 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
upper_limit = frame_parms->ofdm_symbol_size - start_sc;
|
||||
}
|
||||
// fix the alignment issues later, use 64-bit SIMD below instead of 128.
|
||||
// can be made with loadu/storeu
|
||||
if (0/*(frame_parms->N_RB_DL&1)==0*/) {
|
||||
simde__m128i *txF=(simde__m128i*)&txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size+start_sc)<<1)];
|
||||
simde__m128i *txF = (simde__m128i *)&txdataF_precoding[layer][l_symbol][start_sc];
|
||||
|
||||
simde__m128i *txl = (simde__m128i*)&tx_layers[nl][m<<1];
|
||||
simde__m128i *txl = (simde__m128i *)&tx_layers[layer][m];
|
||||
simde__m128i amp128=simde_mm_set1_epi16(amp);
|
||||
for (int i=0; i<(upper_limit>>2); i++) {
|
||||
txF[i] = simde_mm_mulhrs_epi16(amp128,txl[i]);
|
||||
} //RE loop, first part
|
||||
m+=upper_limit;
|
||||
if (remaining_re > 0) {
|
||||
txF = (simde__m128i*)&txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size)<<1)];
|
||||
txl = (simde__m128i*)&tx_layers[nl][m<<1];
|
||||
for (int i=0; i<(remaining_re>>2); i++) {
|
||||
txF[i] = simde_mm_mulhrs_epi16(amp128,txl[i]);
|
||||
}
|
||||
txF = (simde__m128i *)&txdataF_precoding[layer][l_symbol];
|
||||
txl = (simde__m128i *)&tx_layers[layer][m];
|
||||
for (int i = 0; i < (remaining_re >> 2); i++) {
|
||||
txF[i] = simde_mm_mulhrs_epi16(amp128, txl[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
simde__m128i *txF = (simde__m128i *)&txdataF_precoding[nl][((l * frame_parms->ofdm_symbol_size + start_sc) << 1)];
|
||||
simde__m128i *txF = (simde__m128i *)&txdataF_precoding[layer][l_symbol][start_sc];
|
||||
|
||||
simde__m128i *txl = (simde__m128i *)&tx_layers[nl][m << 1];
|
||||
simde__m128i *txl = (simde__m128i *)&tx_layers[layer][m];
|
||||
simde__m128i amp64 = simde_mm_set1_epi16(amp);
|
||||
int i;
|
||||
for (i = 0; i < (upper_limit >> 2); i++) {
|
||||
@@ -421,19 +412,22 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
simde_mm_storeu_si128(txF + i, simde_mm_mulhrs_epi16(amp64, txL));
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
if ((i&1) > 0)
|
||||
printf("m %u\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
m, l, start_sc+(i>>1), txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1)],
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + start_sc+(i>>1))<<1) + 1]);
|
||||
printf("m %u\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
m,
|
||||
l_symbol,
|
||||
start_sc + (i >> 1),
|
||||
txdataF_precoding[layer][l_symbol][start_sc].r,
|
||||
txdataF_precoding[layer][l_symbol][start_sc].i);
|
||||
#endif
|
||||
/* handle this, mute RE */
|
||||
/*else {
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
|
||||
txdataF_precoding[anl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
|
||||
txdataF_precoding[layer][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
|
||||
txdataF_precoding[layer][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
|
||||
}*/
|
||||
}
|
||||
if (i * 4 != upper_limit) {
|
||||
c16_t *txFc = (c16_t *)&txdataF_precoding[nl][((l * frame_parms->ofdm_symbol_size + start_sc) << 1)];
|
||||
c16_t *txlc = (c16_t *)&tx_layers[nl][m << 1];
|
||||
c16_t *txFc = &txdataF_precoding[layer][l_symbol][start_sc];
|
||||
c16_t *txlc = &tx_layers[layer][m];
|
||||
for (i = (upper_limit >> 2) << 2; i < upper_limit; i++) {
|
||||
txFc[i].r = ((txlc[i].r * amp) >> 14) + 1;
|
||||
txFc[i].i = ((txlc[i].i * amp) >> 14) + 1;
|
||||
@@ -441,8 +435,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
}
|
||||
m+=upper_limit;
|
||||
if (remaining_re > 0) {
|
||||
txF = (simde__m128i *)&txdataF_precoding[nl][((l * frame_parms->ofdm_symbol_size) << 1)];
|
||||
txl = (simde__m128i *)&tx_layers[nl][m << 1];
|
||||
txF = (simde__m128i *)&txdataF_precoding[layer][l_symbol];
|
||||
txl = (simde__m128i *)&tx_layers[layer][m];
|
||||
int i;
|
||||
for (i = 0; i < (remaining_re >> 2); i++) {
|
||||
const simde__m128i txL = simde_mm_loadu_si128(txl + i);
|
||||
@@ -451,29 +445,32 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
if ((i&1) > 0)
|
||||
printf("m %u\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
m, l, i>>1, txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) ],
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + (i>>1))<<1) + 1]);
|
||||
m,
|
||||
l_symbol,
|
||||
i >> 1,
|
||||
txdataF_precoding[layer][l_symbol][i >> 1].r,
|
||||
txdataF_precoding[layer][l_symbol][i >> 1].i);
|
||||
#endif
|
||||
/* handle this, mute RE */
|
||||
/*else {
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
|
||||
txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
|
||||
}*/
|
||||
/*else {
|
||||
txdataF_precoding[layer][((l*frame_parms->ofdm_symbol_size + k)<<1) ] = 0;
|
||||
txdataF_precoding[layer][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = 0;
|
||||
}*/
|
||||
} // RE loop, second part
|
||||
if (i * 4 != remaining_re) {
|
||||
c16_t *txFc = (c16_t *)&txdataF_precoding[nl][((l * frame_parms->ofdm_symbol_size) << 1)];
|
||||
c16_t *txlc = (c16_t *)&tx_layers[nl][m << 1];
|
||||
c16_t *txFc = txdataF_precoding[layer][l_symbol];
|
||||
c16_t *txlc = &tx_layers[layer][m];
|
||||
for (i = (remaining_re >> 2) << 2; i < remaining_re; i++) {
|
||||
txFc[i].r = ((txlc[i].r * amp) >> 14) + 1;
|
||||
txFc[i].i = ((txlc[i].i * amp) >> 14) + 1;
|
||||
}
|
||||
}
|
||||
} //
|
||||
} // remaining_re > 0
|
||||
m+=remaining_re;
|
||||
} // N_RB_DL even
|
||||
} // no DMRS/PTRS in symbol
|
||||
} // no DMRS/PTRS in symbol
|
||||
} // symbol loop
|
||||
}// layer loop
|
||||
} // layer loop
|
||||
stop_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
|
||||
///Layer Precoding and Antenna port mapping
|
||||
@@ -484,13 +481,15 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
// The Precoding matrix:
|
||||
// The Codebook Type I
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
c16_t **txdataF = gNB->common_vars.txdataF;
|
||||
|
||||
for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
|
||||
|
||||
for (int l=rel15->StartSymbolIndex; l<rel15->StartSymbolIndex+rel15->NrOfSymbols; l++) {
|
||||
uint16_t k = start_sc;
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
|
||||
uint16_t subCarrier = start_sc;
|
||||
|
||||
for (int rb=0; rb<rel15->rbSize; rb++) {
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * frame_parms->ofdm_symbol_size + txdataF_offset;
|
||||
|
||||
//get pmi info
|
||||
uint8_t pmi;
|
||||
if (0 /*rel15->precodingAndBeamforming.prg_size > 0*/)
|
||||
@@ -499,76 +498,79 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
pmi = 0;//no precoding
|
||||
|
||||
if (pmi == 0) {//unitary Precoding
|
||||
if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC
|
||||
if(ap<rel15->nrOfLayers)
|
||||
memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
|
||||
(void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
if (subCarrier + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][l_symbol][subCarrier],
|
||||
NR_NB_SC_PER_RB * sizeof(**txdataF));
|
||||
else
|
||||
memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
|
||||
0,
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
0,
|
||||
NR_NB_SC_PER_RB * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
int neg_length = frame_parms->ofdm_symbol_size - k;
|
||||
int neg_length = frame_parms->ofdm_symbol_size - subCarrier;
|
||||
int pos_length = NR_NB_SC_PER_RB - neg_length;
|
||||
if (ap<rel15->nrOfLayers) {
|
||||
memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
|
||||
(void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
neg_length*sizeof(int32_t));
|
||||
memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset],
|
||||
(void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)],
|
||||
pos_length*sizeof(int32_t));
|
||||
if (ant < rel15->nrOfLayers) {
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][l_symbol][subCarrier],
|
||||
neg_length * sizeof(**txdataF));
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant][l_symbol], pos_length * sizeof(**txdataF));
|
||||
} else {
|
||||
memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
|
||||
0,
|
||||
neg_length*sizeof(int32_t));
|
||||
memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset],
|
||||
0,
|
||||
pos_length*sizeof(int32_t));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
0,
|
||||
neg_length * sizeof(**txdataF));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol],
|
||||
0,
|
||||
pos_length * sizeof(**txdataF));
|
||||
}
|
||||
}
|
||||
k += NR_NB_SC_PER_RB;
|
||||
if (k >= frame_parms->ofdm_symbol_size) {
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
subCarrier += NR_NB_SC_PER_RB;
|
||||
if (subCarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subCarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(frame_parms->nb_antennas_tx==1){//no precoding matrix defined
|
||||
memcpy((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k],
|
||||
(void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
k += NR_NB_SC_PER_RB;
|
||||
if (k >= frame_parms->ofdm_symbol_size) {
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][l_symbol][subCarrier],
|
||||
NR_NB_SC_PER_RB * sizeof(**txdataF));
|
||||
subCarrier += NR_NB_SC_PER_RB;
|
||||
if (subCarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subCarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//get the precoding matrix weights:
|
||||
int32_t **mat = gNB->nr_mimo_precoding_matrix[rel15->nrOfLayers-1];
|
||||
c16_t **mat = (c16_t**)gNB->nr_mimo_precoding_matrix[rel15->nrOfLayers - 1];
|
||||
//i_row =0,...,dl_antenna_port
|
||||
//j_col =0,...,nrOfLayers
|
||||
//mat[pmi][i_rows*2+j_col]
|
||||
int *W_prec;
|
||||
W_prec = (int32_t *)&mat[pmi][ap*rel15->nrOfLayers];
|
||||
c16_t *W_prec = &mat[pmi][ant * rel15->nrOfLayers];
|
||||
for (int i=0; i<NR_NB_SC_PER_RB; i++) {
|
||||
int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
|
||||
int32_t precodatatx_F = nr_layer_precoder_cm(txdataF_precoding, W_prec, rel15->nrOfLayers, re_offset);
|
||||
((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[0];
|
||||
((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)] = ((int16_t *) &precodatatx_F)[1];
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("antenna %d\t l %d \t k %d \t txdataF: %d %d\n",
|
||||
ap, l, k, ((int16_t*)txdataF[ap])[(re_offset<<1) + (2*txdataF_offset)],
|
||||
((int16_t*)txdataF[ap])[(re_offset<<1) + 1 + (2*txdataF_offset)]);
|
||||
#endif
|
||||
if (++k >= frame_parms->ofdm_symbol_size) {
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] = nr_layer_precoder_cm(rel15->nrOfLayers,
|
||||
NR_SYMBOLS_PER_SLOT,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
txdataF_precoding,
|
||||
W_prec,
|
||||
l_symbol,
|
||||
subCarrier);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n",
|
||||
ant,
|
||||
l_symbol,
|
||||
subCarrier,
|
||||
txdataF[ant][l_symbol * frame_parms->ofdm_symbol_size + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * frame_parms->ofdm_symbol_size + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= frame_parms->ofdm_symbol_size) {
|
||||
subCarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} //RB loop
|
||||
} // symbol loop
|
||||
}// port loop
|
||||
} // port loop
|
||||
|
||||
stop_meas(&gNB->dlsch_precoding_stats);
|
||||
|
||||
@@ -587,9 +589,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
||||
else {
|
||||
LOG_D(PHY,"beam index for PDSCH allocation already taken\n");
|
||||
}
|
||||
for (int layer = 0; layer<rel15->nrOfLayers; layer++)
|
||||
free16(txdataF_precoding[layer],2*14*frame_parms->ofdm_symbol_size);
|
||||
free16(txdataF_precoding,rel15->nrOfLayers);
|
||||
}// dlsch loop
|
||||
}
|
||||
|
||||
|
||||
@@ -74,18 +74,11 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
|
||||
free(harq->c);
|
||||
free(harq->pdu);
|
||||
|
||||
int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
|
||||
for (int q=0; q<nb_codewords; q++)
|
||||
free(dlsch->mod_symbs[q]);
|
||||
free(dlsch->mod_symbs);
|
||||
|
||||
for (int layer = 0; layer < max_layers; layer++) {
|
||||
free(dlsch->txdataF[layer]);
|
||||
for (int aa = 0; aa < 64; aa++)
|
||||
free(dlsch->ue_spec_bf_weights[layer][aa]);
|
||||
free(dlsch->ue_spec_bf_weights[layer]);
|
||||
}
|
||||
free(dlsch->txdataF);
|
||||
free(dlsch->ue_spec_bf_weights);
|
||||
}
|
||||
|
||||
@@ -103,10 +96,6 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment
|
||||
NR_gNB_DLSCH_t dlsch;
|
||||
|
||||
int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer
|
||||
|
||||
dlsch.txdataF = (int32_t **)malloc16(max_layers * sizeof(int32_t *));
|
||||
|
||||
dlsch.ue_spec_bf_weights = (int32_t ***)malloc16(max_layers * sizeof(int32_t **));
|
||||
for (int layer=0; layer<max_layers; layer++) {
|
||||
dlsch.ue_spec_bf_weights[layer] = (int32_t **)malloc16(64 * sizeof(int32_t *));
|
||||
@@ -118,14 +107,8 @@ NR_gNB_DLSCH_t new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t N_RB)
|
||||
dlsch.ue_spec_bf_weights[layer][aa][re] = 0x00007fff;
|
||||
}
|
||||
}
|
||||
dlsch.txdataF[layer] = (int32_t *)malloc16((txdataf_size) * sizeof(int32_t));
|
||||
}
|
||||
|
||||
int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
|
||||
dlsch.mod_symbs = (int32_t **)malloc16(nb_codewords * sizeof(int32_t *));
|
||||
for (int q=0; q<nb_codewords; q++)
|
||||
dlsch.mod_symbs[q] = (int32_t *)malloc16(txdataf_size * max_layers * sizeof(int32_t));
|
||||
|
||||
NR_DL_gNB_HARQ_t *harq = &dlsch.harq_process;
|
||||
bzero(harq, sizeof(NR_DL_gNB_HARQ_t));
|
||||
harq->b = malloc16(dlsch_bytes);
|
||||
|
||||
@@ -65,14 +65,16 @@ void get_antenna_ports(uint8_t *ap, uint8_t n_symbs, uint8_t config) {
|
||||
*(ap+i) = i;
|
||||
}
|
||||
|
||||
void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config) {
|
||||
void get_Wt(int *Wt, const int ap, const nfapi_nr_dmrs_type_e config)
|
||||
{
|
||||
for (int i=0; i<2; i++)
|
||||
*(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]);
|
||||
Wt[i] = (config == NFAPI_NR_DMRS_TYPE1) ? (pdsch_dmrs_1[ap][5 + i]) : (pdsch_dmrs_2[ap][5 + i]);
|
||||
}
|
||||
|
||||
void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config) {
|
||||
void get_Wf(int *Wf, const int ap, const nfapi_nr_dmrs_type_e config)
|
||||
{
|
||||
for (int i=0; i<2; i++)
|
||||
*(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]);
|
||||
Wf[i] = (config == NFAPI_NR_DMRS_TYPE1) ? (pdsch_dmrs_1[ap][3 + i]) : (pdsch_dmrs_2[ap][3 + i]);
|
||||
}
|
||||
|
||||
uint8_t get_delta(uint8_t ap, uint8_t config) {
|
||||
|
||||
@@ -39,10 +39,8 @@
|
||||
#define NR_PDSCH_DMRS_NB_ANTENNA_PORTS 12
|
||||
|
||||
void get_antenna_ports(uint8_t *ap, uint8_t n_symbs, uint8_t config);
|
||||
|
||||
void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config);
|
||||
|
||||
void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config);
|
||||
void get_Wt(int *Wt, const int ap, const nfapi_nr_dmrs_type_e config);
|
||||
void get_Wf(int *Wf, const int ap, const nfapi_nr_dmrs_type_e config);
|
||||
|
||||
uint8_t get_delta(uint8_t ap, uint8_t config);
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
{
|
||||
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
|
||||
|
||||
int8_t Wf[2], Wt[2];
|
||||
int Wf[2], Wt[2];
|
||||
int l_prime[2], delta;
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
int i;
|
||||
|
||||
@@ -193,6 +193,10 @@ extern "C" {
|
||||
};
|
||||
}
|
||||
|
||||
__attribute__((always_inline)) inline c16_t c16mulRealShift(const c16_t a, const int32_t b, const int Shift)
|
||||
{
|
||||
return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)};
|
||||
}
|
||||
__attribute__((always_inline)) inline c16_t c16divShift(const c16_t a, const c16_t b, const int Shift) {
|
||||
return (c16_t) {
|
||||
.r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift),
|
||||
|
||||
@@ -142,10 +142,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
/// Pointers to variables related to DLSCH harq process
|
||||
NR_DL_gNB_HARQ_t harq_process;
|
||||
/// TX buffers for UE-spec transmission (antenna layers 1,...,4 after to precoding)
|
||||
int32_t **txdataF;
|
||||
/// Modulated symbols buffer
|
||||
int32_t **mod_symbs;
|
||||
/// beamforming weights for UE-spec transmission (antenna ports 5 or 7..14), for each codeword, maximum 4 layers?
|
||||
int32_t ***ue_spec_bf_weights;
|
||||
/// Active flag for baseband transmitter processing
|
||||
|
||||
Reference in New Issue
Block a user