Commit 90047871 authored by Laurent THOMAS's avatar Laurent THOMAS

group two symbol loops to make one with smaller tsack size and smaller variables

parent f73afa39
...@@ -738,30 +738,26 @@ c16_t nr_layer_precoder(int sz, c16_t datatx_F_precoding[][sz], const char *prec ...@@ -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, c16_t nr_layer_precoder_cm(int n_layers,
int n_symbols,
int symSz, int symSz,
c16_t datatx_F_precoding[n_layers][n_symbols][symSz], c16_t datatx_F_precoding[n_layers][symSz],
int ap, int ap,
nfapi_nr_pm_pdu_t *pmi_pdu, nfapi_nr_pm_pdu_t *pmi_pdu,
int symbol,
int offset) int offset)
{ {
c16_t precodatatx_F = {0}; c16_t precodatatx_F = {0};
for (int al = 0; al < n_layers; al++) { for (int al = 0; al < n_layers; al++) {
nfapi_nr_pm_weights_t *w = &pmi_pdu->weights[al][ap]; 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}; 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; return precodatatx_F;
} }
void nr_layer_precoder_simd(const int n_layers, void nr_layer_precoder_simd(const int n_layers,
const int n_symbols,
const int symSz, 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 int ant,
const nfapi_nr_pm_pdu_t *pmi_pdu, const nfapi_nr_pm_pdu_t *pmi_pdu,
const int symbol,
const int sc_offset, const int sc_offset,
const int re_cnt, const int re_cnt,
c16_t *txdataF_precoded) c16_t *txdataF_precoded)
...@@ -811,7 +807,7 @@ void nr_layer_precoder_simd(const int n_layers, ...@@ -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 #ifdef DEBUG_DLSCH_PRECODING_PRINT_WITH_TRIVIAL // Get result with trivial solution, TODO: To be removed
c16_t y_triv[4]; c16_t y_triv[4];
for (int i = 0; i < 4; i++) 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)); memcpy(&txdataF_precoded[sc], y_triv, sizeof(y_triv));
#endif #endif
......
...@@ -135,12 +135,10 @@ void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -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(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, c16_t nr_layer_precoder_cm(int n_layers,
int n_symbols,
int symSz, int symSz,
c16_t datatx_F_precoding[n_layers][n_symbols][symSz], c16_t datatx_F_precoding[n_layers][symSz],
int ap, int ap,
nfapi_nr_pm_pdu_t *pmi_pdu, nfapi_nr_pm_pdu_t *pmi_pdu,
int symbol,
int offset); int offset);
/*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[] /*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[]
...@@ -150,12 +148,10 @@ c16_t nr_layer_precoder_cm(int n_layers, ...@@ -150,12 +148,10 @@ c16_t nr_layer_precoder_cm(int n_layers,
@param[out] txdataF_precoded Precoded antenna data @param[out] txdataF_precoded Precoded antenna data
*/ */
void nr_layer_precoder_simd(const int n_layers, void nr_layer_precoder_simd(const int n_layers,
const int n_symbols,
const int symSz, 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 int ant,
const nfapi_nr_pm_pdu_t *pmi_pdu, const nfapi_nr_pm_pdu_t *pmi_pdu,
const int symbol,
const int sc_offset, const int sc_offset,
const int re_cnt, const int re_cnt,
c16_t *txdataF_precoded); c16_t *txdataF_precoded);
......
...@@ -514,6 +514,99 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, ...@@ -514,6 +514,99 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
return txl - txl_start; 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) 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; 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 ...@@ -618,8 +711,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
start_sc -= symbol_sz; start_sc -= symbol_sz;
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP; 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 #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", printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
start_sc, start_sc,
...@@ -634,12 +725,30 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC ...@@ -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))); c16_t mod_dmrs[(n_dmrs+63)&~63] __attribute__((aligned(64)));
unsigned int re_beginning_of_symbol = 0; unsigned int re_beginning_of_symbol = 0;
start_meas(&gNB->dlsch_resource_mapping_stats);
int layerSz2 = (layerSz + 63) & ~63; int layerSz2 = (layerSz + 63) & ~63;
c16_t tx_layers[rel15->nrOfLayers][layerSz2] __attribute__((aligned(64))); c16_t tx_layers[rel15->nrOfLayers][layerSz2] __attribute__((aligned(64)));
memset(tx_layers, 0, sizeof(tx_layers)); memset(tx_layers, 0, sizeof(tx_layers));
nr_layer_mapping(rel15->NrOfCodewords, encoded_length, mod_symbs, rel15->nrOfLayers, layerSz2, nb_re, 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: // Loop Over OFDM symbols:
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) { for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
int l_prime = 0; // single symbol layer 0 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 ...@@ -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) if (rel15->rnti != SI_RNTI)
dmrs_idx += rel15->BWPStart; dmrs_idx += rel15->BWPStart;
dmrs_idx *= dmrs_Type == NFAPI_NR_DMRS_TYPE1 ? 6 : 4; 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; int layer_sz = 0;
for (int layer = 0; layer < rel15->nrOfLayers; layer++) { for (int layer = 0; layer < rel15->nrOfLayers; layer++) {
layer_sz = do_onelayer(frame_parms, layer_sz = do_onelayer(frame_parms,
slot, slot,
rel15, rel15,
layer, layer,
txdataF_precoding[layer][l_symbol], txdataF_precoding[layer],
tx_layers[layer] + re_beginning_of_symbol, tx_layers[layer] + re_beginning_of_symbol,
start_sc, start_sc,
symbol_sz, symbol_sz,
...@@ -705,123 +815,13 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC ...@@ -705,123 +815,13 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
mod_dmrs + dmrs_idx); mod_dmrs + dmrs_idx);
} // layer loop } // layer loop
re_beginning_of_symbol += layer_sz; 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 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;
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset; const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
int rb = 0; do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
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
stop_meas(&gNB->dlsch_precoding_stats); stop_meas(&gNB->dlsch_precoding_stats);
/* output and its parts for each dlsch should be aligned on 64 bytes /* output and its parts for each dlsch should be aligned on 64 bytes
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment