Commit 044ca835 authored by Sakthivel Velumani's avatar Sakthivel Velumani

phy: use fftshift'ed buffer for txdataF

So far txdataF buffer has DC RE as the first element. This was prefered
most likely to avoid memcpy before iFFT but comes with a small
complexity in RE mapping functions.

Instead, we use a flat buffer that holds freq domain data starting from
first negative SC. After resource mapping is done on all channels, each
OFDM symbol is shifted before iFFT so that the buffer start with DC RE.

This reduces complexity in mapping functions and later on when passing
beam IDs to 7.2 split RU especially when a beam is associated to
interleaved RB and/or REs.

There is already a memcpy in place to copy txdataF from gNB stuct to RU
struct. So this change does not introduce new memcpy.
parent d7512bdc
...@@ -103,7 +103,8 @@ void nr_phy_init_RU(RU_t *ru) ...@@ -103,7 +103,8 @@ void nr_phy_init_RU(RU_t *ru)
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)
......
...@@ -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));
}
}
...@@ -67,7 +67,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -67,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,8 +179,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -179,8 +179,6 @@ 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]; 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 */
...@@ -189,8 +187,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -189,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;
...@@ -226,9 +222,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -226,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
......
...@@ -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,9 +591,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC ...@@ -641,9 +591,7 @@ 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;
#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",
......
...@@ -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);
......
...@@ -1619,7 +1619,14 @@ uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot, ...@@ -1619,7 +1619,14 @@ uint8_t 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,7 +25,6 @@ static void csi_rs_resource_mapping(c16_t **dataF, ...@@ -25,7 +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 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,
...@@ -43,7 +42,7 @@ static void csi_rs_resource_mapping(c16_t **dataF, ...@@ -43,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;
...@@ -625,7 +624,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -625,7 +624,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
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,
frame_parms->first_carrier_offset,
phy_csi_parms, phy_csi_parms,
start_rb, start_rb,
nr_of_rbs, nr_of_rbs,
......
...@@ -217,8 +217,6 @@ void nr_feptx(void *arg) ...@@ -217,8 +217,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 = startSymbol * fp->ofdm_symbol_size;
int tx_idx = aa + bb * ru->nb_tx; int tx_idx = aa + bb * ru->nb_tx;
...@@ -232,11 +230,17 @@ void nr_feptx(void *arg) ...@@ -232,11 +230,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_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");
} }
......
...@@ -320,6 +320,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -320,6 +320,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
if (gNB->phase_comp) { if (gNB->phase_comp) {
apply_nr_rotation_TX(fp, apply_nr_rotation_TX(fp,
gNB->common_vars.txdataF[i][aa], 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,
......
...@@ -1141,9 +1141,17 @@ int main(int argc, char **argv) ...@@ -1141,9 +1141,17 @@ int main(int argc, char **argv)
//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], 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,
...@@ -1154,7 +1162,14 @@ int main(int argc, char **argv) ...@@ -1154,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], 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,
......
...@@ -612,21 +612,6 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) ...@@ -612,21 +612,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;
...@@ -662,26 +647,33 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) ...@@ -662,26 +647,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;
...@@ -693,7 +685,7 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) ...@@ -693,7 +685,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 + startRB * N_SC_PER_PRB), (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
...@@ -950,7 +942,6 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t ...@@ -950,7 +942,6 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t
const struct xran_fh_init *fh_init = get_xran_fh_init(); const struct xran_fh_init *fh_init = get_xran_fh_init();
const struct xran_fh_config *fh_cfg = get_xran_fh_config(0); const struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
int nPRBs = fh_cfg->nDLRBs;
int fftsize = 1 << fh_cfg->nDLFftSize; int fftsize = 1 << fh_cfg->nDLFftSize;
int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports;
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
...@@ -1105,36 +1096,32 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t ...@@ -1105,36 +1096,32 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t
} }
uint16_t *dst16 = (uint16_t *)dst; uint16_t *dst16 = (uint16_t *)dst;
int pos_len = 0; int32_t *pos_start = pos + p_prbMapElm->UP_nRBStart * N_SC_PER_PRB;
int neg_len = 0; uint32_t numPrb = p_prbMapElm->UP_nRBSize;
if (p_prbMapElm->UP_nRBStart < (nPRBs >> 1)) // there are PRBs left of DC
neg_len = min((nPRBs * 6) - (p_prbMapElm->UP_nRBStart * 12), p_prbMapElm->UP_nRBSize * N_SC_PER_PRB);
pos_len = (p_prbMapElm->UP_nRBSize * 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) ? ((p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) - (nPRBs * 6)) : 0];
// start of negative frequency component
uint16_t *src2 = (uint16_t *)&pos[(p_prbMapElm->UP_nRBStart * N_SC_PER_PRB) + fftsize - (nPRBs * 6)];
uint32_t local_src[p_prbMapElm->UP_nRBSize * 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 (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) { if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
payload_len = p_prbMapElm->UP_nRBSize * N_SC_PER_PRB * 4L; payload_len = numPrb * 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 < (pos_len + neg_len) * 2; idx++) for (idx = 0; idx < numPrb * N_SC_PER_PRB * 2; idx++)
((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]); ((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) * p_prbMapElm->UP_nRBSize; payload_len = (3 * p_prbMapElm->iqWidth + 1) * numPrb;
/* 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[numPrb * 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, (numPrb * 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 = {};
bfp_com_req.data_in = (int16_t *)local_src; bfp_com_req.data_in = (int16_t *)src_compr;
bfp_com_req.numRBs = p_prbMapElm->UP_nRBSize; bfp_com_req.numRBs = numPrb;
bfp_com_req.len = payload_len; bfp_com_req.len = payload_len;
bfp_com_req.compMethod = p_prbMapElm->compMethod; bfp_com_req.compMethod = p_prbMapElm->compMethod;
bfp_com_req.iqWidth = p_prbMapElm->iqWidth; bfp_com_req.iqWidth = p_prbMapElm->iqWidth;
...@@ -1144,7 +1131,7 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t ...@@ -1144,7 +1131,7 @@ int xran_fh_tx_send_slot_BySymbol(ru_info_t *ru, int frame, int slot, uint64_t t
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, p_prbMapElm->UP_nRBSize, (int16_t *)local_src, (int8_t *)dst); armral_bfp_compression(p_prbMapElm->iqWidth, numPrb, (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