group two symbol loops to make one with smaller tsack size and smaller variables
This commit is contained in:
@@ -276,7 +276,7 @@ void nr_layer_mapping(int nbCodes,
|
||||
for (int i2 = ((n_symbs >> 4) << 4); i2 < n_symbs; i2 += 2) {
|
||||
tx_layers[0][i2 >> 1] = mod_symbs[0][i2];
|
||||
tx_layers[1][i2 >> 1] = mod_symbs[0][i2 + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < n_symbs; i += 32) {
|
||||
@@ -738,30 +738,26 @@ c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec
|
||||
}
|
||||
|
||||
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 datatx_F_precoding[n_layers][symSz],
|
||||
int ap,
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu,
|
||||
int symbol,
|
||||
int offset)
|
||||
{
|
||||
c16_t precodatatx_F = {0};
|
||||
for (int al = 0; al < n_layers; al++) {
|
||||
nfapi_nr_pm_weights_t *w = &pmi_pdu->weights[al][ap];
|
||||
c16_t prec_weight = {.r = w->precoder_weight_Re, .i = w->precoder_weight_Im};
|
||||
precodatatx_F = c16maddShift(datatx_F_precoding[al][symbol][offset], prec_weight, precodatatx_F, 15);
|
||||
precodatatx_F = c16maddShift(datatx_F_precoding[al][offset], prec_weight, precodatatx_F, 15);
|
||||
}
|
||||
return precodatatx_F;
|
||||
}
|
||||
|
||||
void nr_layer_precoder_simd(const int n_layers,
|
||||
const int n_symbols,
|
||||
const int symSz,
|
||||
const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz],
|
||||
const c16_t txdataF_res_mapped[n_layers][symSz],
|
||||
const int ant,
|
||||
const nfapi_nr_pm_pdu_t *pmi_pdu,
|
||||
const int symbol,
|
||||
const int sc_offset,
|
||||
const int re_cnt,
|
||||
c16_t *txdataF_precoded)
|
||||
@@ -811,7 +807,7 @@ void nr_layer_precoder_simd(const int n_layers,
|
||||
#ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Get result with trivial solution, TODO: To be removed
|
||||
c16_t y_triv[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
y_triv[i] = nr_layer_precoder_cm(n_layers, NR_SYMBOLS_PER_SLOT, symSz, txdataF_res_mapped, ant, pmi_pdu, symbol, sc + i);
|
||||
y_triv[i] = nr_layer_precoder_cm(n_layers, symSz, txdataF_res_mapped, ant, pmi_pdu, sc + i);
|
||||
memcpy(&txdataF_precoded[sc], y_triv, sizeof(y_triv));
|
||||
#endif
|
||||
|
||||
|
||||
@@ -135,12 +135,10 @@ void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *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 datatx_F_precoding[n_layers][symSz],
|
||||
int ap,
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu,
|
||||
int symbol,
|
||||
int offset);
|
||||
|
||||
/*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[]
|
||||
@@ -150,13 +148,11 @@ c16_t nr_layer_precoder_cm(int n_layers,
|
||||
@param[out] txdataF_precoded Precoded antenna data
|
||||
*/
|
||||
void nr_layer_precoder_simd(const int n_layers,
|
||||
const int n_symbols,
|
||||
const int symSz,
|
||||
const c16_t txdataF_res_mapped[n_layers][n_symbols][symSz],
|
||||
const int ant,
|
||||
const nfapi_nr_pm_pdu_t *pmi_pdu,
|
||||
const int symbol,
|
||||
const int sc_offset,
|
||||
const int re_cnt,
|
||||
c16_t *txdataF_precoded);
|
||||
const int symSz,
|
||||
const c16_t txdataF_res_mapped[n_layers][symSz],
|
||||
const int ant,
|
||||
const nfapi_nr_pm_pdu_t *pmi_pdu,
|
||||
const int sc_offset,
|
||||
const int re_cnt,
|
||||
c16_t *txdataF_precoded);
|
||||
#endif
|
||||
|
||||
@@ -514,6 +514,99 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
return txl - txl_start;
|
||||
}
|
||||
|
||||
static inline void do_txdataF(c16_t **txdataF,
|
||||
int symbol_sz,
|
||||
c16_t txdataF_precoding[][symbol_sz],
|
||||
PHY_VARS_gNB *gNB,
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
int ant,
|
||||
int start_sc,
|
||||
int txdataF_offset_per_symbol)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
int rb = 0;
|
||||
uint16_t subCarrier = start_sc;
|
||||
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
while (rb < rel15->rbSize) {
|
||||
// get pmi info
|
||||
const int pmi = (pb->num_prgs > 0 && pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
|
||||
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1;
|
||||
|
||||
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
|
||||
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
|
||||
const int rb_step = pmi == pmi2 ? 2 : 1;
|
||||
const int re_cnt = NR_NB_SC_PER_RB * rb_step;
|
||||
|
||||
if (pmi == 0) { // unitary Precoding
|
||||
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
const int neg_length = symbol_sz - subCarrier;
|
||||
const int pos_length = re_cnt - neg_length;
|
||||
if (ant < rel15->nrOfLayers) {
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
neg_length * sizeof(**txdataF));
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant], pos_length * sizeof(**txdataF));
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
}
|
||||
subCarrier += re_cnt;
|
||||
if (subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
} else { // non-unitary Precoding
|
||||
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
|
||||
// get the precoding matrix weights:
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu = &gNB->gNB_config.pmi_list.pmi_pdu[pmi - 1]; // pmi 0 is identity matrix
|
||||
AssertFatal(pmi == pmi_pdu->pm_idx, "PMI %d doesn't match to the one in precoding matrix %d\n", pmi, pmi_pdu->pm_idx);
|
||||
AssertFatal(ant < pmi_pdu->num_ant_ports,
|
||||
"Antenna port index %d exceeds precoding matrix AP size %d\n",
|
||||
ant,
|
||||
pmi_pdu->num_ant_ports);
|
||||
AssertFatal(rel15->nrOfLayers == pmi_pdu->numLayers,
|
||||
"Number of layers %d doesn't match to the one in precoding matrix %d\n",
|
||||
rel15->nrOfLayers,
|
||||
pmi_pdu->numLayers);
|
||||
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} else { // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
for (int i = 0; i < re_cnt; i++) {
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] =
|
||||
nr_layer_precoder_cm(rel15->nrOfLayers, symbol_sz, txdataF_precoding, ant, pmi_pdu, 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 * symbol_sz + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
}
|
||||
} // else{ // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
} // else { // non-unitary Precoding
|
||||
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
}
|
||||
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot)
|
||||
{
|
||||
const int16_t amp = gNB->TX_AMP;
|
||||
@@ -618,8 +711,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
start_sc -= symbol_sz;
|
||||
|
||||
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
|
||||
c16_t txdataF_precoding[rel15->nrOfLayers][NR_NUMBER_OF_SYMBOLS_PER_SLOT][symbol_sz] __attribute__((aligned(64)));
|
||||
memset(txdataF_precoding, 0, sizeof(txdataF_precoding));
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
|
||||
start_sc,
|
||||
@@ -634,12 +725,30 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
c16_t mod_dmrs[(n_dmrs+63)&~63] __attribute__((aligned(64)));
|
||||
unsigned int re_beginning_of_symbol = 0;
|
||||
|
||||
start_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
int layerSz2 = (layerSz + 63) & ~63;
|
||||
c16_t tx_layers[rel15->nrOfLayers][layerSz2] __attribute__((aligned(64)));
|
||||
memset(tx_layers, 0, sizeof(tx_layers));
|
||||
nr_layer_mapping(rel15->NrOfCodewords, encoded_length, mod_symbs, rel15->nrOfLayers, layerSz2, nb_re, tx_layers);
|
||||
|
||||
/// Layer Precoding and Antenna port mapping
|
||||
// tx_layers 1-8 are mapped on antenna ports 1000-1007
|
||||
// The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
|
||||
// The same precoding matrix is applied on prg_size RBs, Thus
|
||||
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
|
||||
// The Precoding matrix:
|
||||
// The Codebook Type I
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
// beam number in multi-beam scenario (concurrent beams)
|
||||
int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols);
|
||||
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
bitmap);
|
||||
|
||||
c16_t **txdataF = gNB->common_vars.txdataF[beam_nb];
|
||||
|
||||
// Loop Over OFDM symbols:
|
||||
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
|
||||
int l_prime = 0; // single symbol layer 0
|
||||
@@ -685,13 +794,14 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
if (rel15->rnti != SI_RNTI)
|
||||
dmrs_idx += rel15->BWPStart;
|
||||
dmrs_idx *= dmrs_Type == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
|
||||
c16_t txdataF_precoding[rel15->nrOfLayers][symbol_sz] __attribute__((aligned(64)));
|
||||
int layer_sz = 0;
|
||||
for (int layer = 0; layer < rel15->nrOfLayers; layer++) {
|
||||
layer_sz = do_onelayer(frame_parms,
|
||||
slot,
|
||||
rel15,
|
||||
layer,
|
||||
txdataF_precoding[layer][l_symbol],
|
||||
txdataF_precoding[layer],
|
||||
tx_layers[layer] + re_beginning_of_symbol,
|
||||
start_sc,
|
||||
symbol_sz,
|
||||
@@ -705,123 +815,13 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
mod_dmrs + dmrs_idx);
|
||||
} // layer loop
|
||||
re_beginning_of_symbol += layer_sz;
|
||||
} // symbol loop
|
||||
stop_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
stop_meas(&gNB->dlsch_resource_mapping_stats);
|
||||
|
||||
/// Layer Precoding and Antenna port mapping
|
||||
// tx_layers 1-8 are mapped on antenna ports 1000-1007
|
||||
// The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
|
||||
// The same precoding matrix is applied on prg_size RBs, Thus
|
||||
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
|
||||
// The Precoding matrix:
|
||||
// The Codebook Type I
|
||||
start_meas(&gNB->dlsch_precoding_stats);
|
||||
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
|
||||
// beam number in multi-beam scenario (concurrent beams)
|
||||
int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols);
|
||||
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
|
||||
&gNB->common_vars,
|
||||
slot,
|
||||
frame_parms->symbols_per_slot,
|
||||
bitmap);
|
||||
|
||||
c16_t **txdataF = gNB->common_vars.txdataF[beam_nb];
|
||||
|
||||
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 ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
|
||||
int rb = 0;
|
||||
|
||||
while (rb < rel15->rbSize) {
|
||||
// get pmi info
|
||||
const int pmi = (pb->num_prgs > 0 && pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
|
||||
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1;
|
||||
|
||||
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
|
||||
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
|
||||
const int rb_step = pmi == pmi2 ? 2 : 1;
|
||||
const int re_cnt = NR_NB_SC_PER_RB * rb_step;
|
||||
|
||||
if (pmi == 0) { // unitary Precoding
|
||||
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][l_symbol][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
const int neg_length = symbol_sz - subCarrier;
|
||||
const int pos_length = re_cnt - neg_length;
|
||||
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(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, neg_length * sizeof(**txdataF));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol], 0, pos_length * sizeof(**txdataF));
|
||||
}
|
||||
}
|
||||
subCarrier += re_cnt;
|
||||
if (subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
} else { // non-unitary Precoding
|
||||
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
|
||||
// get the precoding matrix weights:
|
||||
nfapi_nr_pm_pdu_t *pmi_pdu = &gNB->gNB_config.pmi_list.pmi_pdu[pmi - 1]; // pmi 0 is identity matrix
|
||||
AssertFatal(pmi == pmi_pdu->pm_idx, "PMI %d doesn't match to the one in precoding matrix %d\n", pmi, pmi_pdu->pm_idx);
|
||||
AssertFatal(ant < pmi_pdu->num_ant_ports,
|
||||
"Antenna port index %d exceeds precoding matrix AP size %d\n",
|
||||
ant,
|
||||
pmi_pdu->num_ant_ports);
|
||||
AssertFatal(rel15->nrOfLayers == pmi_pdu->numLayers,
|
||||
"Number of layers %d doesn't match to the one in precoding matrix %d\n",
|
||||
rel15->nrOfLayers,
|
||||
pmi_pdu->numLayers);
|
||||
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
NR_SYMBOLS_PER_SLOT,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
l_symbol,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} else { // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
for (int i = 0; i < re_cnt; i++) {
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] = nr_layer_precoder_cm(rel15->nrOfLayers,
|
||||
NR_SYMBOLS_PER_SLOT,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
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 * symbol_sz + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
}
|
||||
} // else{ // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
} // else { // non-unitary Precoding
|
||||
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
} // symbol loop
|
||||
} // port loop
|
||||
do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
|
||||
}
|
||||
}
|
||||
|
||||
stop_meas(&gNB->dlsch_precoding_stats);
|
||||
/* output and its parts for each dlsch should be aligned on 64 bytes
|
||||
|
||||
Reference in New Issue
Block a user