Commit 592cb8ac authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/gnb-txdataF-flatbuff' into integration_2026_w11 (!3834)

Use flat buffer for txdataF in gNB L1

This MR changes txdataF buffer format to hold freq domain data starting from
PRB0 instead of circular buffer that starts from PRB N/2. The motive is to
simplify RE mapping function in L1 and copying data to xran lib.
parents 6fa541fe 044ca835
...@@ -185,7 +185,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) ...@@ -185,7 +185,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
for (int i = 0; i < common_vars->num_beams_period; i++) { for (int i = 0; i < common_vars->num_beams_period; i++) {
common_vars->txdataF[i] = (c16_t**)malloc16_clear(Ptx * sizeof(c16_t*)); common_vars->txdataF[i] = (c16_t**)malloc16_clear(Ptx * sizeof(c16_t*));
for (int j = 0; j < Ptx; j++) for (int j = 0; j < Ptx; j++)
common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(c16_t)); common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_slot_wCP * sizeof(c16_t));
} }
common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100); common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100);
common_vars->debugBuff_sample_offset = 0; common_vars->debugBuff_sample_offset = 0;
......
...@@ -97,13 +97,14 @@ void nr_phy_init_RU(RU_t *ru) ...@@ -97,13 +97,14 @@ void nr_phy_init_RU(RU_t *ru)
ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); ru->common.txdataF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*));
// [hna] samples_per_frame without CP // [hna] samples_per_frame without CP
for(int i = 0; i < ru->nb_tx; ++i) for(int i = 0; i < ru->nb_tx; ++i)
ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); ru->common.txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_slot_wCP * sizeof(int32_t));
// allocate IFFT input buffers (TX) // allocate IFFT input buffers (TX)
ru->common.txdataF_BF = (int32_t **)malloc16(nb_tx_streams * sizeof(int32_t*)); ru->common.txdataF_BF = (int32_t **)malloc16(nb_tx_streams * sizeof(int32_t*));
LOG_D(PHY, "[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, nb_tx_streams * sizeof(int32_t *)); LOG_D(PHY, "[INIT] common.txdata_BF= %p (%lu bytes)\n", ru->common.txdataF_BF, nb_tx_streams * sizeof(int32_t *));
for (int i = 0; i < nb_tx_streams; i++) { for (int i = 0; i < nb_tx_streams; i++) {
ru->common.txdataF_BF[i] = (int32_t*)malloc16_clear(fp->samples_per_subframe_wCP * sizeof(int32_t)); ru->common.txdataF_BF[i] =
(int32_t *)malloc16_clear(fp->samples_per_slot_wCP * sizeof(int32_t));
LOG_D(PHY, "txdataF_BF[%d] %p for RU %d\n", i, ru->common.txdataF_BF[i], ru->idx); LOG_D(PHY, "txdataF_BF[%d] %p for RU %d\n", i, ru->common.txdataF_BF[i], ru->idx);
} }
// allocate FFT output buffers (RX) // allocate FFT output buffers (RX)
......
...@@ -265,7 +265,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) ...@@ -265,7 +265,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_CSI_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal)); ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_CSI_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal));
for (int i = 0; i < NR_MAX_CSI_PORTS; i++) { for (int i = 0; i < NR_MAX_CSI_PORTS; i++) {
ue->nr_csi_info->csi_rs_generated_signal[i] = ue->nr_csi_info->csi_rs_generated_signal[i] =
malloc16_clear(fp->samples_per_frame_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal)); malloc16_clear(fp->samples_per_slot_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal));
} }
ue->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t)); ue->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t));
......
...@@ -105,6 +105,7 @@ void nr_beam_precoding(c16_t **txdataF, ...@@ -105,6 +105,7 @@ void nr_beam_precoding(c16_t **txdataF,
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
c16_t *txdataF, c16_t *txdataF,
bool is_flat_buff,
const c16_t *symbol_rotation, const c16_t *symbol_rotation,
int slot, int slot,
int nb_rb, int nb_rb,
...@@ -161,4 +162,12 @@ void nr_layer_precoder_simd(const int n_layers, ...@@ -161,4 +162,12 @@ void nr_layer_precoder_simd(const int n_layers,
const int sc_offset, const int sc_offset,
const int re_cnt, const int re_cnt,
c16_t *txdataF_precoded); c16_t *txdataF_precoded);
void fft_shift(const c16_t *in,
uint32_t in_symb_sz,
uint16_t num_prb,
c16_t *out,
uint16_t fft_size_out,
uint16_t start_symb,
uint16_t num_symb);
#endif #endif
...@@ -288,6 +288,7 @@ void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_s ...@@ -288,6 +288,7 @@ void do_OFDM_mod(c16_t **txdataF, c16_t **txdata, uint32_t frame,uint16_t next_s
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
c16_t *txdataF, c16_t *txdataF,
bool is_flat_buff,
const c16_t *symbol_rotation, const c16_t *symbol_rotation,
int slot, int slot,
int nb_rb, int nb_rb,
...@@ -309,20 +310,39 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, ...@@ -309,20 +310,39 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
this_rotation->r, this_rotation->r,
this_rotation->i); this_rotation->i);
if (nb_rb & 1) { if (is_flat_buff)
rotate_cpx_vector(this_symbol, this_rotation, this_symbol, rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * NR_NB_SC_PER_RB, 15);
(nb_rb + 1) * 6, 15); else {
rotate_cpx_vector(this_symbol + fp->first_carrier_offset - 6, c16_t *this_symbol_neg = this_symbol + fp->first_carrier_offset;
this_rotation, if (nb_rb & 1) {
this_symbol + fp->first_carrier_offset - 6, this_symbol_neg -= 6;
(nb_rb + 1) * 6, 15); nb_rb += 1;
} else { }
rotate_cpx_vector(this_symbol, this_rotation, this_symbol, rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * 6, 15);
nb_rb * 6, 15); rotate_cpx_vector(this_symbol_neg, this_rotation, this_symbol_neg, nb_rb * 6, 15);
rotate_cpx_vector(this_symbol + fp->first_carrier_offset,
this_rotation,
this_symbol + fp->first_carrier_offset,
nb_rb * 6, 15);
} }
} }
} }
/* Do FFT-shift for symbols in the provided in buffer and writes to out buffer. */
void fft_shift(const c16_t *in,
uint32_t in_symb_sz,
uint16_t num_prb,
c16_t *out,
uint16_t fft_size_out,
uint16_t start_symb,
uint16_t num_symb)
{
const int num_samp_half = num_prb * NR_NB_SC_PER_RB / 2;
const int first_carrier_offset = fft_size_out - num_samp_half;
for (int s = start_symb; s < start_symb + num_symb; s++) {
// Copy negative freq component
uint16_t out_offset = s * fft_size_out + first_carrier_offset;
uint16_t in_offset = s * in_symb_sz;
memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t));
// Copy positive freq component
out_offset = s * fft_size_out;
in_offset = s * in_symb_sz + num_samp_half;
memcpy(out + out_offset, in + in_offset, num_samp_half * sizeof(int32_t));
}
}
...@@ -53,7 +53,6 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3 ...@@ -53,7 +53,6 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3
void nr_generate_dci(PHY_VARS_gNB *gNB, void nr_generate_dci(PHY_VARS_gNB *gNB,
const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int txdataF_offset,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
int slot) int slot)
{ {
...@@ -68,7 +67,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -68,7 +67,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
if (pdcch_pdu_rel15->CoreSetType == 1) if (pdcch_pdu_rel15->CoreSetType == 1)
additional_offset = (pdcch_pdu_rel15->BWPStart + 5) / 6 * 6 - pdcch_pdu_rel15->BWPStart; additional_offset = (pdcch_pdu_rel15->BWPStart + 5) / 6 * 6 - pdcch_pdu_rel15->BWPStart;
int rb_offset = cset_start + additional_offset; int rb_offset = cset_start + additional_offset;
uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; uint16_t cset_start_sc = (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols; int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols;
int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 3) + 15) & ~15; int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 3) + 15) & ~15;
c16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16))); c16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16)));
...@@ -179,9 +178,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -179,9 +178,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
/// Resource mapping /// Resource mapping
uint16_t amp = gNB->TX_AMP; uint16_t amp = gNB->TX_AMP;
c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0] + txdataF_offset; c16_t *txdataF = gNB->common_vars.txdataF[beam_nb][0];
if (cset_start_sc >= frame_parms->ofdm_symbol_size)
cset_start_sc -= frame_parms->ofdm_symbol_size;
int num_regs = dci_pdu->AggregationLevel * NR_NB_REG_PER_CCE / pdcch_pdu_rel15->DurationSymbols; int num_regs = dci_pdu->AggregationLevel * NR_NB_REG_PER_CCE / pdcch_pdu_rel15->DurationSymbols;
/*Mapping the encoded DCI along with the DMRS */ /*Mapping the encoded DCI along with the DMRS */
...@@ -190,8 +187,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -190,8 +187,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
for (int reg_count = 0; reg_count < num_regs; reg_count++) { for (int reg_count = 0; reg_count < num_regs; reg_count++) {
int k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB; int k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB;
LOG_D(NR_PHY_DCI, "REG %d k %d\n", reg_list[d][reg_count], k); LOG_D(NR_PHY_DCI, "REG %d k %d\n", reg_list[d][reg_count], k);
if (k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
int l = cset_start_symb + symbol_idx; int l = cset_start_symb + symbol_idx;
...@@ -227,9 +222,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -227,9 +222,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
} }
k++; k++;
if (k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
} // m } // m
} // reg_count } // reg_count
} // symbol_idx } // symbol_idx
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
void nr_generate_dci(PHY_VARS_gNB *gNB, void nr_generate_dci(PHY_VARS_gNB *gNB,
const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int txdataF_offset,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
int slot); int slot);
......
...@@ -86,8 +86,7 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15, ...@@ -86,8 +86,7 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
printf("k %d \t txdataF: %d %d\n", k, txF[k].r, txF[k].i); printf("k %d \t txdataF: %d %d\n", k, txF[k].r, txF[k].i);
#endif #endif
} }
if (++k >= symbol_sz) k++;
k -= symbol_sz;
} }
return in - tx_layer; return in - tx_layer;
} }
...@@ -294,7 +293,7 @@ static inline int dmrs_case00(c16_t *output, ...@@ -294,7 +293,7 @@ static inline int dmrs_case00(c16_t *output,
else { else {
output[k] = (c16_t){0}; output[k] = (c16_t){0};
} }
k = (k + 1) % symbol_sz; k++;
} // RE loop } // RE loop
return in - txl; return in - txl;
} }
...@@ -355,12 +354,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, ...@@ -355,12 +354,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
{ {
c16_t *txl = txl_start; c16_t *txl = txl_start;
const uint sz = rel15->rbSize * NR_NB_SC_PER_RB; const uint sz = rel15->rbSize * NR_NB_SC_PER_RB;
int upper_limit = sz;
int remaining_re = 0;
if (start_sc + upper_limit > symbol_sz) {
upper_limit = symbol_sz - start_sc;
remaining_re = sz - upper_limit;
}
/* calculate if current symbol is PTRS symbols */ /* calculate if current symbol is PTRS symbols */
int ptrs_symbol = 0; int ptrs_symbol = 0;
...@@ -385,47 +378,39 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, ...@@ -385,47 +378,39 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
if (rel15->numDmrsCdmGrpsNoData == 2) { if (rel15->numDmrsCdmGrpsNoData == 2) {
switch (dmrs_port & 3) { switch (dmrs_port & 3) {
case 0: case 0:
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, upper_limit); txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, sz);
txl += interleave_with_0_signal_first(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break; break;
case 1: { case 1: {
c16_t dmrs[sz / 2]; c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2); neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, upper_limit); txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, sz);
txl += interleave_with_0_signal_first(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break; } break;
case 2: case 2:
txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, upper_limit); txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, sz);
txl += interleave_with_0_start_with_0(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break; break;
case 3: { case 3: {
c16_t dmrs[sz / 2]; c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2); neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, upper_limit); txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, sz);
txl += interleave_with_0_start_with_0(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break; } break;
} }
} else if (rel15->numDmrsCdmGrpsNoData == 1) { } else if (rel15->numDmrsCdmGrpsNoData == 1) {
switch (dmrs_port & 3) { switch (dmrs_port & 3) {
case 0: case 0:
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, upper_limit); txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, sz);
txl += interleave_signals(output, txl, amp, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break; break;
case 1: { case 1: {
c16_t dmrs[sz / 2]; c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2); neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, upper_limit); txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, sz);
txl += interleave_signals(output, txl, amp, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break; } break;
case 2: case 2:
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, upper_limit); txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, sz);
txl += interleave_signals(output, dmrs_start + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
break; break;
case 3: { case 3: {
c16_t dmrs[sz / 2]; c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2); neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, upper_limit); txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, sz);
txl += interleave_signals(output, dmrs + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
} break; } break;
} }
} else } else
...@@ -445,8 +430,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, ...@@ -445,8 +430,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
rel15->numDmrsCdmGrpsNoData); rel15->numDmrsCdmGrpsNoData);
} // generic DMRS case } // generic DMRS case
} else { // no PTRS or DMRS in this symbol } else { // no PTRS or DMRS in this symbol
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, upper_limit); txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz);
txl += no_ptrs_dmrs_case(output, txl, amp, remaining_re);
} // no DMRS/PTRS in symbol } // no DMRS/PTRS in symbol
return txl - txl_start; return txl - txl_start;
} }
...@@ -477,30 +461,13 @@ static inline void do_txdataF(c16_t **txdataF, ...@@ -477,30 +461,13 @@ static inline void do_txdataF(c16_t **txdataF,
const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0; const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0;
const int re_cnt = NR_NB_SC_PER_RB * rb_step; const int re_cnt = NR_NB_SC_PER_RB * rb_step;
if (pmi == 0) { // unitary Precoding if (pmi == 0) { // unitary Precoding
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC if (ant < rel15->nrOfLayers)
if (ant < rel15->nrOfLayers) memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], &txdataF_precoding[ant][subCarrier],
&txdataF_precoding[ant][subCarrier], re_cnt * sizeof(**txdataF));
re_cnt * sizeof(**txdataF)); else
else memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
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; subCarrier += re_cnt;
if (subCarrier >= symbol_sz) {
subCarrier -= symbol_sz;
}
} else { // non-unitary Precoding } else { // non-unitary Precoding
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n"); AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
// get the precoding matrix weights: // get the precoding matrix weights:
...@@ -514,38 +481,21 @@ static inline void do_txdataF(c16_t **txdataF, ...@@ -514,38 +481,21 @@ static inline void do_txdataF(c16_t **txdataF,
"Number of layers %d doesn't match to the one in precoding matrix %d\n", "Number of layers %d doesn't match to the one in precoding matrix %d\n",
rel15->nrOfLayers, rel15->nrOfLayers,
pmi_pdu->numLayers); pmi_pdu->numLayers);
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe nr_layer_precoder_simd(rel15->nrOfLayers,
nr_layer_precoder_simd(rel15->nrOfLayers, symbol_sz,
symbol_sz, txdataF_precoding,
txdataF_precoding, ant,
ant, pmi_pdu,
pmi_pdu, subCarrier,
subCarrier, re_cnt,
re_cnt, &txdataF[ant][txdataF_offset_per_symbol]);
&txdataF[ant][txdataF_offset_per_symbol]); subCarrier += re_cnt;
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 } // else { // non-unitary Precoding
rb += rb_step; rb += rb_step;
} // RB loop: while(rb < rel15->rbSize) } // 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;
...@@ -641,11 +591,8 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC ...@@ -641,11 +591,8 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
start_meas(&gNB->dlsch_pdsch_generation_stats); start_meas(&gNB->dlsch_pdsch_generation_stats);
/// Resource mapping /// Resource mapping
// Non interleaved VRB to PRB mapping // Non interleaved VRB to PRB mapping
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB; uint16_t start_sc = (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
if (start_sc >= symbol_sz)
start_sc -= symbol_sz;
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
#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,
...@@ -756,7 +703,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC ...@@ -756,7 +703,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
start_meas(&gNB->dlsch_precoding_stats); start_meas(&gNB->dlsch_precoding_stats);
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) { for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset; const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz;
do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol); do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
} }
stop_meas(&gNB->dlsch_precoding_stats); stop_meas(&gNB->dlsch_precoding_stats);
......
...@@ -71,7 +71,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -71,7 +71,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
/// Resource mapping /// Resource mapping
// PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3 // PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols ///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; k = frame_parms->ssb_start_subcarrier + nushift;
l = ssb_start_symbol + 1; l = ssb_start_symbol + 1;
for (int m = 0; m < 60; m++) { for (int m = 0; m < 60; m++) {
...@@ -80,13 +80,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -80,13 +80,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#endif #endif
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15); txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
k+=4; k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols ///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; k = frame_parms->ssb_start_subcarrier + nushift;
l++; l++;
for (int m = 60; m < 84; m++) { for (int m = 60; m < 84; m++) {
...@@ -100,13 +97,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -100,13 +97,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]);
#endif #endif
k+=(m==71)?148:4; // Jump from 44+nu to 192+nu k+=(m==71)?148:4; // Jump from 44+nu to 192+nu
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols ///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; k = frame_parms->ssb_start_subcarrier + nushift;
l++; l++;
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) { for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
...@@ -115,9 +109,6 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -115,9 +109,6 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
#endif #endif
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15); txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
k+=4; k+=4;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
#ifdef DEBUG_PBCH_DMRS #ifdef DEBUG_PBCH_DMRS
...@@ -334,7 +325,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, ...@@ -334,7 +325,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
nushift = config->cell_config.phy_cell_id.value &3; nushift = config->cell_config.phy_cell_id.value &3;
// PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS // PBCH modulated symbols are mapped within the SSB block on symbols 1, 2, 3 excluding the subcarriers used for the PBCH DMRS
///symbol 1 [0:239] -- 180 mod symbols ///symbol 1 [0:239] -- 180 mod symbols
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; int k = frame_parms->ssb_start_subcarrier;
int l = ssb_start_symbol + 1; int l = ssb_start_symbol + 1;
int m = 0; int m = 0;
int16_t amp = gNB->TX_AMP; int16_t amp = gNB->TX_AMP;
...@@ -351,13 +342,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, ...@@ -351,13 +342,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
k++; k++;
m++; m++;
} }
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
///symbol 2 [0:47 ; 192:239] -- 72 mod symbols ///symbol 2 [0:47 ; 192:239] -- 72 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; k = frame_parms->ssb_start_subcarrier;
l++; l++;
m=180; m=180;
...@@ -373,16 +361,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, ...@@ -373,16 +361,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
k++; k++;
m++; m++;
} }
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
k += 144; k += 144;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
m=216; m=216;
for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) { for (int ssb_sc_idx = 192; ssb_sc_idx < 240; ssb_sc_idx++) {
...@@ -397,13 +379,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, ...@@ -397,13 +379,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
k++; k++;
m++; m++;
} }
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
///symbol 3 [0:239] -- 180 mod symbols ///symbol 3 [0:239] -- 180 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; k = frame_parms->ssb_start_subcarrier;
l++; l++;
m=252; m=252;
...@@ -419,9 +398,5 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB, ...@@ -419,9 +398,5 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
k++; k++;
m++; m++;
} }
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
} }
...@@ -51,9 +51,9 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg ...@@ -51,9 +51,9 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg
else if (prs_cfg->CombSize == 12){ else if (prs_cfg->CombSize == 12){
k_prime = k_prime_table[3][symInd]; k_prime = k_prime_table[3][symInd];
} }
k = (prs_cfg->REOffset+k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset*12 + frame_parms->first_carrier_offset; k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12;
// QPSK modulation // QPSK modulation
uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l); uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l);
for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) { for (int m = 0; m < (12/prs_cfg->CombSize) * prs_cfg->NumRB; m++) {
...@@ -66,10 +66,7 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg ...@@ -66,10 +66,7 @@ int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_prs[m], amp, 15); txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_prs[m], amp, 15);
k = k + prs_cfg->CombSize; k = k + prs_cfg->CombSize;
}
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
}
} }
#ifdef DEBUG_PRS_MAP #ifdef DEBUG_PRS_MAP
LOG_M("nr_prs.m", "prs",(int16_t *)&txdataF[prs_cfg->SymbolStart*frame_parms->ofdm_symbol_size],prs_cfg->NumPRSSymbols*frame_parms->ofdm_symbol_size, 1, 1); LOG_M("nr_prs.m", "prs",(int16_t *)&txdataF[prs_cfg->SymbolStart*frame_parms->ofdm_symbol_size],prs_cfg->NumPRSSymbols*frame_parms->ofdm_symbol_size, 1, 1);
......
...@@ -49,8 +49,7 @@ int nr_generate_pss( c16_t *txdataF, ...@@ -49,8 +49,7 @@ int nr_generate_pss( c16_t *txdataF,
/// Resource mapping /// Resource mapping
// PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from // PSS occupies a predefined position (subcarriers 56-182, symbol 0) within the SSB block starting from
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and int k = frame_parms->ssb_start_subcarrier + 56;
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
int l = ssb_start_symbol; int l = ssb_start_symbol;
...@@ -61,9 +60,6 @@ int nr_generate_pss( c16_t *txdataF, ...@@ -61,9 +60,6 @@ int nr_generate_pss( c16_t *txdataF,
// printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size); // printf("pss: writing position k %d / %d\n",k,frame_parms->ofdm_symbol_size);
((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_pss) >> 15; ((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_pss) >> 15;
k++; k++;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
#ifdef NR_PSS_DEBUG #ifdef NR_PSS_DEBUG
......
...@@ -59,16 +59,13 @@ int nr_generate_sss( c16_t *txdataF, ...@@ -59,16 +59,13 @@ int nr_generate_sss( c16_t *txdataF,
/// Resource mapping /// Resource mapping
// SSS occupies a predefined position (subcarriers 56-182, symbol 2) within the SSB block starting from // SSS occupies a predefined position (subcarriers 56-182, symbol 2) within the SSB block starting from
int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; //and int k = frame_parms->ssb_start_subcarrier + 56;
int l = ssb_start_symbol + 2; int l = ssb_start_symbol + 2;
for (int i = 0; i < NR_SSS_LENGTH; i++) { for (int i = 0; i < NR_SSS_LENGTH; i++) {
int16_t d_sss = (1 - 2*x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2*x1[(i + m1) % NR_SSS_LENGTH] ) * 23170; int16_t d_sss = (1 - 2*x0[(i + m0) % NR_SSS_LENGTH] ) * (1 - 2*x1[(i + m1) % NR_SSS_LENGTH] ) * 23170;
((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15; ((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15;
k++; k++;
if (k >= frame_parms->ofdm_symbol_size)
k-=frame_parms->ofdm_symbol_size;
} }
#ifdef NR_SSS_DEBUG #ifdef NR_SSS_DEBUG
// write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1); // write_output("sss_0.m", "sss_0", (void*)txdataF[0][l*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
......
...@@ -281,7 +281,6 @@ static int nr_csi_rs_channel_estimation( ...@@ -281,7 +281,6 @@ static int nr_csi_rs_channel_estimation(
int16_t *log2_maxh, int16_t *log2_maxh,
uint32_t *noise_power) uint32_t *noise_power)
{ {
const int dataF_offset = proc->nr_slot_rx * fp->samples_per_slot_wCP;
*noise_power = 0; *noise_power = 0;
int maxh = 0; int maxh = 0;
int count = 0; int count = 0;
...@@ -316,7 +315,7 @@ static int nr_csi_rs_channel_estimation( ...@@ -316,7 +315,7 @@ static int nr_csi_rs_channel_estimation(
for (int lp = 0; lp <= csi_mapping->lprime; lp++) { for (int lp = 0; lp <= csi_mapping->lprime; lp++) {
uint16_t symb = lp + csi_mapping->loverline[cdm_id]; uint16_t symb = lp + csi_mapping->loverline[cdm_id];
uint64_t symbol_offset = symb * fp->ofdm_symbol_size; uint64_t symbol_offset = symb * fp->ofdm_symbol_size;
const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset];
const c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset]; const c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset];
c16_t tmp = c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits); c16_t tmp = c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits);
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions // This is not just the LS estimation for each (k,l), but also the sum of the different contributions
......
...@@ -1619,7 +1619,14 @@ void nr_tx_rotation_and_ofdm_mod(const uint8_t slot, ...@@ -1619,7 +1619,14 @@ void nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
if (was_symbol_used[i] == false) if (was_symbol_used[i] == false)
continue; continue;
for (int ap = 0; ap < n_antenna_ports; ap++) { for (int ap = 0; ap < n_antenna_ports; ap++) {
apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1); apply_nr_rotation_TX(frame_parms,
txdataF[ap],
false,
frame_parms->symbol_rotation[linktype],
slot,
N_RB,
i,
1);
} }
} }
} }
......
...@@ -25,8 +25,6 @@ static void csi_rs_resource_mapping(c16_t **dataF, ...@@ -25,8 +25,6 @@ static void csi_rs_resource_mapping(c16_t **dataF,
int csi_rs_length, int csi_rs_length,
int16_t mod_csi[][csi_rs_length >> 1], int16_t mod_csi[][csi_rs_length >> 1],
int ofdm_symbol_size, int ofdm_symbol_size,
int dataF_offset,
int start_sc,
const csi_mapping_parms_t *mapping_parms, const csi_mapping_parms_t *mapping_parms,
int start_rb, int start_rb,
int nb_rbs, int nb_rbs,
...@@ -44,7 +42,7 @@ static void csi_rs_resource_mapping(c16_t **dataF, ...@@ -44,7 +42,7 @@ static void csi_rs_resource_mapping(c16_t **dataF,
int p = s + mapping_parms->j[ji] * gs; // port index int p = s + mapping_parms->j[ji] * gs; // port index
for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group
// frequency index of current resource element // frequency index of current resource element
int k = (start_sc + (n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp) % (ofdm_symbol_size); int k = ((n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp);
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5 // wf according to tables 7.4.5.3-2 to 7.4.5.3-5
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1); int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
int na = n * alpha; int na = n * alpha;
...@@ -66,7 +64,7 @@ static void csi_rs_resource_mapping(c16_t **dataF, ...@@ -66,7 +64,7 @@ static void csi_rs_resource_mapping(c16_t **dataF,
else else
wt = -1; wt = -1;
} }
int index = (l * ofdm_symbol_size + k) + dataF_offset; int index = (l * ofdm_symbol_size + k);
dataF[p][index].r = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15; dataF[p][index].r = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15;
dataF[p][index].i = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15; dataF[p][index].i = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15;
LOG_D(PHY, LOG_D(PHY,
...@@ -622,14 +620,10 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -622,14 +620,10 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
// CDM group size from CDM type index // CDM group size from CDM type index
const int gs = get_cdm_group_size(cdm_type); const int gs = get_cdm_group_size(cdm_type);
const int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
csi_rs_resource_mapping(dataF, csi_rs_resource_mapping(dataF,
frame_parms->N_RB_DL << 4, frame_parms->N_RB_DL << 4,
mod_csi, mod_csi,
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
dataF_offset,
frame_parms->first_carrier_offset,
phy_csi_parms, phy_csi_parms,
start_rb, start_rb,
nr_of_rbs, nr_of_rbs,
......
...@@ -173,7 +173,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx) ...@@ -173,7 +173,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
PHY_VARS_gNB *gNB = gNB_list[0]; PHY_VARS_gNB *gNB = gNB_list[0];
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
int txdataF_offset = slot_tx * fp->samples_per_slot_wCP;
start_meas(&ru->precoding_stats); start_meas(&ru->precoding_stats);
if (gNB->common_vars.analog_bf) { if (gNB->common_vars.analog_bf) {
...@@ -193,8 +192,8 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx) ...@@ -193,8 +192,8 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
for (int b = 0; b < ru->num_beams_period; b++) { for (int b = 0; b < ru->num_beams_period; b++) {
for (int i = 0; i < Ptx; ++i) { for (int i = 0; i < Ptx; ++i) {
int tx_idx = i + b * ru->nb_tx; int tx_idx = i + b * ru->nb_tx;
memcpy((void*)ru->common.txdataF_BF[tx_idx], memcpy((void *)ru->common.txdataF_BF[tx_idx],
(void*)&gNB->common_vars.txdataF[b][i][txdataF_offset], (void *)gNB->common_vars.txdataF[b][i],
fp->samples_per_slot_wCP * sizeof(int32_t)); fp->samples_per_slot_wCP * sizeof(int32_t));
} }
} }
...@@ -216,9 +215,6 @@ void nr_feptx(void *arg) ...@@ -216,9 +215,6 @@ void nr_feptx(void *arg)
int startSymbol = feptx->startSymbol; int startSymbol = feptx->startSymbol;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
int numSymbols = feptx->numSymbols; int numSymbols = feptx->numSymbols;
int numSamples = feptx->numSymbols * fp->ofdm_symbol_size;
int txdataF_offset = (slot * fp->samples_per_slot_wCP) + startSymbol * fp->ofdm_symbol_size;
int txdataF_BF_offset = startSymbol * fp->ofdm_symbol_size;
int tx_idx = aa + bb * ru->nb_tx; int tx_idx = aa + bb * ru->nb_tx;
...@@ -232,11 +228,17 @@ void nr_feptx(void *arg) ...@@ -232,11 +228,17 @@ void nr_feptx(void *arg)
} }
// If there is no digital beamforming we just need to copy the data to RU // If there is no digital beamforming we just need to copy the data to RU
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset], // FFT shift
(void*)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset], const NR_DL_FRAME_PARMS *fp = &ru->gNB_list[0]->frame_parms;
numSamples * sizeof(int32_t)); fft_shift(ru->gNB_list[0]->common_vars.txdataF[bb][aa],
else { fp->ofdm_symbol_size,
fp->N_RB_DL,
(c16_t *)ru->common.txdataF_BF[tx_idx],
fp->ofdm_symbol_size,
startSymbol,
numSymbols);
} else {
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n"); AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
} }
......
...@@ -146,7 +146,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n ...@@ -146,7 +146,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol);
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming;
c16_t ***txdataF = gNB->common_vars.txdataF; c16_t ***txdataF = gNB->common_vars.txdataF;
int txdataF_offset = slot * fp->samples_per_slot_wCP;
// beam number in a scenario with multiple concurrent beams // beam number in a scenario with multiple concurrent beams
int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols
int beam_nb = beam_index_allocation(gNB->enable_analog_das, int beam_nb = beam_index_allocation(gNB->enable_analog_das,
...@@ -156,15 +155,15 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n ...@@ -156,15 +155,15 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
fp->symbols_per_slot, fp->symbols_per_slot,
bitmap); bitmap);
nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); nr_generate_pss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(txdataF[beam_nb][0], gNB->TX_AMP, ssb_start_symbol, cfg, fp);
uint16_t slots_per_hf = (fp->slots_per_frame) >> 1; uint16_t slots_per_hf = (fp->slots_per_frame) >> 1;
int n_hf = slot < slots_per_hf ? 0 : 1; int n_hf = slot < slots_per_hf ? 0 : 1;
int hf = fp->Lmax == 4 ? n_hf : 0; int hf = fp->Lmax == 4 ? n_hf : 0;
nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7), nr_generate_pbch_dmrs(nr_gold_pbch(fp->Lmax, gNB->gNB_config.cell_config.phy_cell_id.value, hf, ssb_index & 7),
&txdataF[beam_nb][0][txdataF_offset], txdataF[beam_nb][0],
gNB->TX_AMP, gNB->TX_AMP,
ssb_start_symbol, ssb_start_symbol,
cfg, cfg,
...@@ -182,7 +181,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n ...@@ -182,7 +181,7 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
nr_generate_pbch(gNB, nr_generate_pbch(gNB,
ssb_pdu, ssb_pdu,
&txdataF[beam_nb][0][txdataF_offset], txdataF[beam_nb][0],
ssb_start_symbol, ssb_start_symbol,
n_hf, n_hf,
frame, frame,
...@@ -246,7 +245,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -246,7 +245,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
{ {
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
const int txdataF_offset = slot * fp->samples_per_slot_wCP;
if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) if ((cfg->cell_config.frame_duplex_type.value == TDD) && (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT))
return; return;
...@@ -254,7 +252,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -254,7 +252,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
// clear the transmit data array and beam index for the current slot // clear the transmit data array and beam index for the current slot
for (int i = 0; i < gNB->common_vars.num_beams_period; i++) { for (int i = 0; i < gNB->common_vars.num_beams_period; i++) {
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
memset(&gNB->common_vars.txdataF[i][aa][txdataF_offset], 0, fp->samples_per_slot_wCP * sizeof(***gNB->common_vars.txdataF)); memset(gNB->common_vars.txdataF[i][aa], 0, fp->samples_per_slot_wCP * sizeof(***gNB->common_vars.txdataF));
} }
} }
...@@ -268,13 +266,13 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -268,13 +266,13 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
{ {
int slot_prs = (slot - i * prs_config->PRSResourceTimeGap + fp->slots_per_frame) % fp->slots_per_frame; int slot_prs = (slot - i * prs_config->PRSResourceTimeGap + fp->slots_per_frame) % fp->slots_per_frame;
LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id); LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id);
nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, fp); nr_generate_prs(slot_prs, gNB->common_vars.txdataF[0][0], AMP, prs_config, fp);
} }
} }
} }
for (int i = 0; i < UL_dci_req->numPdus; ++i) for (int i = 0; i < UL_dci_req->numPdus; ++i)
nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); nr_generate_dci(gNB, &UL_dci_req->ul_dci_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15, &gNB->frame_parms, slot);
int num_pdsch = 0; int num_pdsch = 0;
for (int i = 0; i < DL_req->dl_tti_request_body.nPDUs; ++i) { for (int i = 0; i < DL_req->dl_tti_request_body.nPDUs; ++i) {
...@@ -284,7 +282,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -284,7 +282,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
nr_common_signal_procedures(gNB, frame, slot, &dl_tti_pdu->ssb_pdu); nr_common_signal_procedures(gNB, frame, slot, &dl_tti_pdu->ssb_pdu);
break; break;
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, &gNB->frame_parms, slot);
break; break;
case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
nr_generate_csi_rs_gNB(gNB, slot, &dl_tti_pdu->csi_rs_pdu); nr_generate_csi_rs_gNB(gNB, slot, &dl_tti_pdu->csi_rs_pdu);
...@@ -321,7 +319,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -321,7 +319,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) { for (int aa = 0; aa < cfg->carrier_config.num_tx_ant.value; aa++) {
if (gNB->phase_comp) { if (gNB->phase_comp) {
apply_nr_rotation_TX(fp, apply_nr_rotation_TX(fp,
&gNB->common_vars.txdataF[i][aa][txdataF_offset], gNB->common_vars.txdataF[i][aa],
true,
fp->symbol_rotation[0], fp->symbol_rotation[0],
slot, slot,
fp->N_RB_DL, fp->N_RB_DL,
...@@ -333,7 +332,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -333,7 +332,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
T_INT(frame), T_INT(frame),
T_INT(slot), T_INT(slot),
T_INT(aa), T_INT(aa),
T_BUFFER(&gNB->common_vars.txdataF[i][aa][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t))); T_BUFFER(gNB->common_vars.txdataF[i][aa], fp->samples_per_slot_wCP * sizeof(int32_t)));
} }
} }
stop_meas(&gNB->phase_comp_stats); stop_meas(&gNB->phase_comp_stats);
......
...@@ -1123,29 +1123,35 @@ int main(int argc, char **argv) ...@@ -1123,29 +1123,35 @@ int main(int argc, char **argv)
phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot); phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot);
stop_meas(&gNB->phy_proc_tx); stop_meas(&gNB->phy_proc_tx);
int txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
if (n_trials==1) { if (n_trials==1) {
LOG_M("txsigF0.m","txsF0=", LOG_M("txsigF0.m","txsF0=",
&gNB->common_vars.txdataF[0][0][txdataF_offset +2 * frame_parms->ofdm_symbol_size], &gNB->common_vars.txdataF[0][0][2 * frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
1, 1,
1); 1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1=", LOG_M("txsigF1.m","txsF1=",
&gNB->common_vars.txdataF[0][1][txdataF_offset + 2 * frame_parms->ofdm_symbol_size], &gNB->common_vars.txdataF[0][1][2 * frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
1, 1,
1); 1);
} }
if (n_trials == 1) if (n_trials == 1)
printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset); printf("slot_offset %d\n", slot_offset);
//TODO: loop over slots //TODO: loop over slots
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
c16_t fft_in_buff[frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot] __attribute__((aligned(64)));
memset(fft_in_buff, 0, sizeof(fft_in_buff));
if (cyclic_prefix_type == 1) { if (cyclic_prefix_type == 1) {
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][txdataF_offset], fft_shift(gNB->common_vars.txdataF[0][aa],
frame_parms->ofdm_symbol_size,
frame_parms->N_RB_DL,
fft_in_buff,
frame_parms->ofdm_symbol_size,
0,
12);
PHY_ofdm_mod((int *)fft_in_buff,
(int *)&txdata[aa][slot_offset], (int *)&txdata[aa][slot_offset],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
12, 12,
...@@ -1156,7 +1162,14 @@ int main(int argc, char **argv) ...@@ -1156,7 +1162,14 @@ int main(int argc, char **argv)
for (int i = 0; i < 14; i++) { for (int i = 0; i < 14; i++) {
was_symbol_used[i] = true; was_symbol_used[i] = true;
} }
nr_normal_prefix_mod(&gNB->common_vars.txdataF[0][aa][txdataF_offset], fft_shift(gNB->common_vars.txdataF[0][aa],
frame_parms->ofdm_symbol_size,
frame_parms->N_RB_DL,
fft_in_buff,
frame_parms->ofdm_symbol_size,
0,
14);
nr_normal_prefix_mod(fft_in_buff,
&txdata[aa][slot_offset], &txdata[aa][slot_offset],
14, 14,
frame_parms, frame_parms,
......
...@@ -525,17 +525,28 @@ int main(int argc, char **argv) ...@@ -525,17 +525,28 @@ int main(int argc, char **argv)
nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]); nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]);
int samp = get_samples_slot_timestamp(frame_parms, slot); int samp = get_samples_slot_timestamp(frame_parms, slot);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { for (aa = 0; aa < gNB->frame_parms.nb_antennas_tx; aa++) {
c16_t fft_in_buff[frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot] __attribute__((aligned(64)));
memset(fft_in_buff, 0, sizeof(fft_in_buff));
if (cyclic_prefix_type == 1) { if (cyclic_prefix_type == 1) {
apply_nr_rotation_TX(frame_parms, apply_nr_rotation_TX(frame_parms,
gNB->common_vars.txdataF[0][aa], gNB->common_vars.txdataF[0][aa],
true,
frame_parms->symbol_rotation[0], frame_parms->symbol_rotation[0],
slot, slot,
frame_parms->N_RB_DL, frame_parms->N_RB_DL,
0, 0,
12); 12);
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], fft_shift(gNB->common_vars.txdataF[0][aa],
frame_parms->ofdm_symbol_size,
frame_parms->N_RB_DL,
fft_in_buff,
frame_parms->ofdm_symbol_size,
0,
12);
PHY_ofdm_mod((int *)fft_in_buff,
(int *)&txdata[aa][samp], (int *)&txdata[aa][samp],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
12, 12,
...@@ -544,21 +555,30 @@ int main(int argc, char **argv) ...@@ -544,21 +555,30 @@ int main(int argc, char **argv)
} else { } else {
apply_nr_rotation_TX(frame_parms, apply_nr_rotation_TX(frame_parms,
gNB->common_vars.txdataF[0][aa], gNB->common_vars.txdataF[0][aa],
true,
frame_parms->symbol_rotation[0], frame_parms->symbol_rotation[0],
slot, slot,
frame_parms->N_RB_DL, frame_parms->N_RB_DL,
0, 0,
14); 14);
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa], fft_shift(gNB->common_vars.txdataF[0][aa],
(int*)&txdata[aa][samp], frame_parms->ofdm_symbol_size,
frame_parms->N_RB_DL,
fft_in_buff,
frame_parms->ofdm_symbol_size,
0,
14);
PHY_ofdm_mod((int *)fft_in_buff,
(int *)&txdata[aa][samp],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
1, 1,
frame_parms->nb_prefix_samples0, frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX); CYCLIC_PREFIX);
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][frame_parms->ofdm_symbol_size], PHY_ofdm_mod((int *)fft_in_buff + frame_parms->ofdm_symbol_size,
(int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size], (int *)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size, frame_parms->ofdm_symbol_size,
13, 13,
frame_parms->nb_prefix_samples, frame_parms->nb_prefix_samples,
...@@ -567,9 +587,9 @@ int main(int argc, char **argv) ...@@ -567,9 +587,9 @@ int main(int argc, char **argv)
} }
} }
} }
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0][0],frame_length_complex_samples_no_prefix, 1, 1); LOG_M("txsigF0.m", "txsF0", gNB->common_vars.txdataF[0][0], frame_parms->samples_per_slot_wCP, 1, 1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx > 1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[0][1],frame_length_complex_samples_no_prefix, 1, 1); LOG_M("txsigF1.m", "txsF1", gNB->common_vars.txdataF[0][1], frame_parms->samples_per_slot_wCP, 1, 1);
} else { } else {
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
......
...@@ -654,21 +654,6 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) ...@@ -654,21 +654,6 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
int num_totalRB = p_prbMapElm->nRBSize; int num_totalRB = p_prbMapElm->nRBSize;
int start_totalRB = p_prbMapElm->nRBStart; int start_totalRB = p_prbMapElm->nRBStart;
int pos_len = 0;
int neg_len = 0;
if (start_totalRB < (num_totalRB >> 1)) // there are PRBs left of DC
neg_len = min((num_totalRB * 6) - (start_totalRB * 12), num_totalRB * N_SC_PER_PRB);
pos_len = (num_totalRB * N_SC_PER_PRB) - neg_len;
// Calculation of the pointer for the section in the buffer.
// start of positive frequency component
uint16_t *src1 = (uint16_t *)&pos[(neg_len == 0) ? ((start_totalRB * N_SC_PER_PRB) - (num_totalRB * 6)) : 0];
// start of negative frequency component
uint16_t *src2 = (uint16_t *)&pos[(start_totalRB * N_SC_PER_PRB) + fftsize - (num_totalRB * 6)];
uint32_t local_src[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64)));
memcpy((void *)local_src, (void *)src2, neg_len * 4);
memcpy((void *)&local_src[neg_len], (void *)src1, pos_len * 4);
if (ptr && pos) { if (ptr && pos) {
u8dptr = (uint8_t *)ptr; u8dptr = (uint8_t *)ptr;
int16_t payload_len = 0; int16_t payload_len = 0;
...@@ -728,26 +713,33 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) ...@@ -728,26 +713,33 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
uint16_t *dst16 = (uint16_t *)dst; uint16_t *dst16 = (uint16_t *)dst;
// Start of this section
int32_t *pos_start = pos + (start_totalRB + startRB) * N_SC_PER_PRB;
if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) { if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
payload_len = numRB * N_SC_PER_PRB * 4L; payload_len = numRB * N_SC_PER_PRB * 4L;
/* convert to Network order */ /* convert to Network order */
// NOTE: ggc 11 knows how to generate AVX2 for this! // NOTE: ggc 11 knows how to generate AVX2 for this!
for (idx = 0; idx < (numRB * N_SC_PER_PRB) * 2; idx++) for (idx = 0; idx < (numRB * N_SC_PER_PRB) * 2; idx++)
((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx + startRB * N_SC_PER_PRB * 2]); ((uint16_t *)dst16)[idx] = htons(((uint16_t *)pos_start)[idx]);
} else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) { } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
payload_len = (3 * p_prbMapElm->iqWidth + 1) * numRB; payload_len = (3 * p_prbMapElm->iqWidth + 1) * numRB;
/* Although arm intrinsics natively handle unaligned memory
access, we use a 64 byte aligned input here for maximum
performance. So the src_compr buffer is used for both x86 and arm.
*/
uint32_t src_compr[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64)));
/* Copy from txdataF with current symbol's PRB start (nRBStart) +
current section's PRB start (UP_nPRBStart) */
memcpy(src_compr, pos_start, (numRB * N_SC_PER_PRB) * sizeof(*pos_start));
#if defined(__i386__) || defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
struct xranlib_compress_request bfp_com_req = {}; struct xranlib_compress_request bfp_com_req = {};
struct xranlib_compress_response bfp_com_rsp = {}; struct xranlib_compress_response bfp_com_rsp = {};
uint32_t src_compr[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64))); bfp_com_req.data_in = (int16_t *)src_compr;
if (numRB == num_totalRB) {
bfp_com_req.data_in = (int16_t *)local_src;
} else {
memcpy(src_compr, local_src + (startRB * N_SC_PER_PRB), (numRB * N_SC_PER_PRB) * sizeof(*local_src));
bfp_com_req.data_in = (int16_t *)src_compr;
}
bfp_com_req.numRBs = numRB; bfp_com_req.numRBs = numRB;
bfp_com_req.len = payload_len; bfp_com_req.len = payload_len;
...@@ -759,7 +751,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) ...@@ -759,7 +751,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp)
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp); xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
#elif defined(__arm__) || defined(__aarch64__) #elif defined(__arm__) || defined(__aarch64__)
armral_bfp_compression(p_prbMapElm->iqWidth, numRB, (int16_t *)local_src, (int8_t *)dst); armral_bfp_compression(p_prbMapElm->iqWidth, numRB, (int16_t *)src_compr, (int8_t *)dst);
#else #else
AssertFatal(1 == 0, "BFP compression not supported on this architecture"); AssertFatal(1 == 0, "BFP compression not supported on this architecture");
#endif #endif
......
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