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.
This commit is contained in:
@@ -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*));
|
||||
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++) {
|
||||
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);
|
||||
}
|
||||
// allocate FFT output buffers (RX)
|
||||
|
||||
@@ -105,6 +105,7 @@ void nr_beam_precoding(c16_t **txdataF,
|
||||
|
||||
void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
c16_t *txdataF,
|
||||
bool is_flat_buff,
|
||||
const c16_t *symbol_rotation,
|
||||
int slot,
|
||||
int nb_rb,
|
||||
@@ -161,4 +162,12 @@ void nr_layer_precoder_simd(const int n_layers,
|
||||
const int sc_offset,
|
||||
const int re_cnt,
|
||||
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
|
||||
|
||||
@@ -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,
|
||||
c16_t *txdataF,
|
||||
bool is_flat_buff,
|
||||
const c16_t *symbol_rotation,
|
||||
int slot,
|
||||
int nb_rb,
|
||||
@@ -309,20 +310,39 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
|
||||
this_rotation->r,
|
||||
this_rotation->i);
|
||||
|
||||
if (nb_rb & 1) {
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol,
|
||||
(nb_rb + 1) * 6, 15);
|
||||
rotate_cpx_vector(this_symbol + fp->first_carrier_offset - 6,
|
||||
this_rotation,
|
||||
this_symbol + fp->first_carrier_offset - 6,
|
||||
(nb_rb + 1) * 6, 15);
|
||||
} else {
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol,
|
||||
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);
|
||||
if (is_flat_buff)
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * NR_NB_SC_PER_RB, 15);
|
||||
else {
|
||||
c16_t *this_symbol_neg = this_symbol + fp->first_carrier_offset;
|
||||
if (nb_rb & 1) {
|
||||
this_symbol_neg -= 6;
|
||||
nb_rb += 1;
|
||||
}
|
||||
rotate_cpx_vector(this_symbol, this_rotation, this_symbol, nb_rb * 6, 15);
|
||||
rotate_cpx_vector(this_symbol_neg, this_rotation, this_symbol_neg, 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,
|
||||
if (pdcch_pdu_rel15->CoreSetType == 1)
|
||||
additional_offset = (pdcch_pdu_rel15->BWPStart + 5) / 6 * 6 - pdcch_pdu_rel15->BWPStart;
|
||||
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 idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 3) + 15) & ~15;
|
||||
c16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16)));
|
||||
@@ -179,8 +179,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
/// Resource mapping
|
||||
uint16_t amp = gNB->TX_AMP;
|
||||
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;
|
||||
/*Mapping the encoded DCI along with the DMRS */
|
||||
@@ -189,8 +187,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
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;
|
||||
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;
|
||||
|
||||
@@ -226,9 +222,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
} // m
|
||||
} // reg_count
|
||||
} // symbol_idx
|
||||
|
||||
@@ -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);
|
||||
#endif
|
||||
}
|
||||
if (++k >= symbol_sz)
|
||||
k -= symbol_sz;
|
||||
k++;
|
||||
}
|
||||
return in - tx_layer;
|
||||
}
|
||||
@@ -294,7 +293,7 @@ static inline int dmrs_case00(c16_t *output,
|
||||
else {
|
||||
output[k] = (c16_t){0};
|
||||
}
|
||||
k = (k + 1) % symbol_sz;
|
||||
k++;
|
||||
} // RE loop
|
||||
return in - txl;
|
||||
}
|
||||
@@ -355,12 +354,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
{
|
||||
c16_t *txl = txl_start;
|
||||
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 */
|
||||
int ptrs_symbol = 0;
|
||||
@@ -385,47 +378,39 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
if (rel15->numDmrsCdmGrpsNoData == 2) {
|
||||
switch (dmrs_port & 3) {
|
||||
case 0:
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
|
||||
txl += interleave_with_0_signal_first(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, sz);
|
||||
break;
|
||||
case 1: {
|
||||
c16_t 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, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, sz);
|
||||
} break;
|
||||
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, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, sz);
|
||||
break;
|
||||
case 3: {
|
||||
c16_t 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, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, sz);
|
||||
} break;
|
||||
}
|
||||
} else if (rel15->numDmrsCdmGrpsNoData == 1) {
|
||||
switch (dmrs_port & 3) {
|
||||
case 0:
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, upper_limit);
|
||||
txl += interleave_signals(output, txl, amp, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, sz);
|
||||
break;
|
||||
case 1: {
|
||||
c16_t 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, txl, amp, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, sz);
|
||||
} break;
|
||||
case 2:
|
||||
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, upper_limit);
|
||||
txl += interleave_signals(output, dmrs_start + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, sz);
|
||||
break;
|
||||
case 3: {
|
||||
c16_t 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, dmrs + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
|
||||
txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, sz);
|
||||
} break;
|
||||
}
|
||||
} else
|
||||
@@ -445,8 +430,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
rel15->numDmrsCdmGrpsNoData);
|
||||
} // generic DMRS case
|
||||
} 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, txl, amp, remaining_re);
|
||||
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz);
|
||||
} // no DMRS/PTRS in symbol
|
||||
return txl - txl_start;
|
||||
}
|
||||
@@ -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 re_cnt = NR_NB_SC_PER_RB * rb_step;
|
||||
if (pmi == 0) { // unitary Precoding
|
||||
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
} else { // RB does cross DC
|
||||
const int neg_length = symbol_sz - subCarrier;
|
||||
const int pos_length = re_cnt - neg_length;
|
||||
if (ant < rel15->nrOfLayers) {
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
neg_length * sizeof(**txdataF));
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol], &txdataF_precoding[ant], pos_length * sizeof(**txdataF));
|
||||
} else {
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, neg_length * sizeof(**txdataF));
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol], 0, pos_length * sizeof(**txdataF));
|
||||
}
|
||||
}
|
||||
if (ant < rel15->nrOfLayers)
|
||||
memcpy(&txdataF[ant][txdataF_offset_per_symbol + subCarrier],
|
||||
&txdataF_precoding[ant][subCarrier],
|
||||
re_cnt * sizeof(**txdataF));
|
||||
else
|
||||
memset(&txdataF[ant][txdataF_offset_per_symbol + subCarrier], 0, re_cnt * sizeof(**txdataF));
|
||||
subCarrier += re_cnt;
|
||||
if (subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
} else { // non-unitary Precoding
|
||||
AssertFatal(frame_parms->nb_antennas_tx > 1, "No precoding can be done with a single antenna port\n");
|
||||
// get the precoding matrix weights:
|
||||
@@ -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",
|
||||
rel15->nrOfLayers,
|
||||
pmi_pdu->numLayers);
|
||||
if ((subCarrier + re_cnt) < symbol_sz) { // within ofdm_symbol_size, use SIMDe
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} else { // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
for (int i = 0; i < re_cnt; i++) {
|
||||
txdataF[ant][txdataF_offset_per_symbol + subCarrier] =
|
||||
nr_layer_precoder_cm(rel15->nrOfLayers, symbol_sz, txdataF_precoding, ant, pmi_pdu, subCarrier);
|
||||
#ifdef DEBUG_DLSCH_MAPPING
|
||||
printf("antenna %d\t l %d \t subCarrier %d \t txdataF: %d %d\n",
|
||||
ant,
|
||||
l_symbol,
|
||||
subCarrier,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].r,
|
||||
txdataF[ant][l_symbol * symbol_sz + subCarrier + txdataF_offset].i);
|
||||
#endif
|
||||
if (++subCarrier >= symbol_sz) {
|
||||
subCarrier -= symbol_sz;
|
||||
}
|
||||
}
|
||||
} // else{ // crossing ofdm_symbol_size, use simple arithmetic operations
|
||||
nr_layer_precoder_simd(rel15->nrOfLayers,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
ant,
|
||||
pmi_pdu,
|
||||
subCarrier,
|
||||
re_cnt,
|
||||
&txdataF[ant][txdataF_offset_per_symbol]);
|
||||
subCarrier += re_cnt;
|
||||
} // else { // non-unitary Precoding
|
||||
|
||||
rb += rb_step;
|
||||
} // RB loop: while(rb < rel15->rbSize)
|
||||
}
|
||||
|
||||
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot)
|
||||
{
|
||||
const int16_t amp = gNB->TX_AMP;
|
||||
@@ -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);
|
||||
/// Resource 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;
|
||||
if (start_sc >= symbol_sz)
|
||||
start_sc -= symbol_sz;
|
||||
uint16_t start_sc = (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
|
||||
|
||||
#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",
|
||||
|
||||
@@ -71,7 +71,7 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
/// Resource mapping
|
||||
// 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
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
|
||||
k = frame_parms->ssb_start_subcarrier + nushift;
|
||||
l = ssb_start_symbol + 1;
|
||||
|
||||
for (int m = 0; m < 60; m++) {
|
||||
@@ -80,13 +80,10 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
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
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
|
||||
k = frame_parms->ssb_start_subcarrier + nushift;
|
||||
l++;
|
||||
|
||||
for (int m = 60; m < 84; m++) {
|
||||
@@ -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]);
|
||||
#endif
|
||||
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
|
||||
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
|
||||
k = frame_parms->ssb_start_subcarrier + nushift;
|
||||
l++;
|
||||
|
||||
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
|
||||
@@ -115,9 +109,6 @@ void nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||
#endif
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_dmrs[m], amp, 15);
|
||||
k+=4;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PBCH_DMRS
|
||||
@@ -334,7 +325,7 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
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
|
||||
///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 m = 0;
|
||||
int16_t amp = gNB->TX_AMP;
|
||||
@@ -351,13 +342,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
///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++;
|
||||
m=180;
|
||||
|
||||
@@ -373,16 +361,10 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
k += 144;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
|
||||
m=216;
|
||||
|
||||
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,
|
||||
k++;
|
||||
m++;
|
||||
}
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
///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++;
|
||||
m=252;
|
||||
|
||||
@@ -419,9 +398,5 @@ void nr_generate_pbch(PHY_VARS_gNB *gNB,
|
||||
k++;
|
||||
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
|
||||
else if (prs_cfg->CombSize == 12){
|
||||
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
|
||||
uint32_t *gold = nr_gold_prs(prs_cfg->NPRSID, slot, l);
|
||||
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
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k] = c16mulRealShift(mod_prs[m], amp, 15);
|
||||
|
||||
k = k + prs_cfg->CombSize;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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);
|
||||
|
||||
@@ -49,8 +49,7 @@ int nr_generate_pss( c16_t *txdataF,
|
||||
/// Resource mapping
|
||||
|
||||
// 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
|
||||
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
|
||||
int k = frame_parms->ssb_start_subcarrier + 56;
|
||||
|
||||
int l = ssb_start_symbol;
|
||||
|
||||
@@ -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);
|
||||
((int16_t*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_pss) >> 15;
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
#ifdef NR_PSS_DEBUG
|
||||
|
||||
@@ -59,16 +59,13 @@ int nr_generate_sss( c16_t *txdataF,
|
||||
/// Resource mapping
|
||||
|
||||
// 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;
|
||||
|
||||
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*)txdataF)[2*(l*frame_parms->ofdm_symbol_size + k)] = (((int16_t)amp) * d_sss) >> 15;
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k-=frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
#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);
|
||||
|
||||
@@ -1619,7 +1619,14 @@ uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
|
||||
if (was_symbol_used[i] == false)
|
||||
continue;
|
||||
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,
|
||||
int csi_rs_length,
|
||||
int16_t mod_csi[][csi_rs_length >> 1],
|
||||
int ofdm_symbol_size,
|
||||
int start_sc,
|
||||
const csi_mapping_parms_t *mapping_parms,
|
||||
int start_rb,
|
||||
int nb_rbs,
|
||||
@@ -43,7 +42,7 @@ static void csi_rs_resource_mapping(c16_t **dataF,
|
||||
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
|
||||
// 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
|
||||
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
|
||||
int na = n * alpha;
|
||||
@@ -625,7 +624,6 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
frame_parms->N_RB_DL << 4,
|
||||
mod_csi,
|
||||
frame_parms->ofdm_symbol_size,
|
||||
frame_parms->first_carrier_offset,
|
||||
phy_csi_parms,
|
||||
start_rb,
|
||||
nr_of_rbs,
|
||||
|
||||
@@ -217,8 +217,6 @@ void nr_feptx(void *arg)
|
||||
int startSymbol = feptx->startSymbol;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
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;
|
||||
|
||||
@@ -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 (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],
|
||||
(void *)&ru->gNB_list[0]->common_vars.txdataF[bb][aa][txdataF_offset],
|
||||
numSamples * sizeof(int32_t));
|
||||
else {
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
// FFT shift
|
||||
const NR_DL_FRAME_PARMS *fp = &ru->gNB_list[0]->frame_parms;
|
||||
fft_shift(ru->gNB_list[0]->common_vars.txdataF[bb][aa],
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +320,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
if (gNB->phase_comp) {
|
||||
apply_nr_rotation_TX(fp,
|
||||
gNB->common_vars.txdataF[i][aa],
|
||||
true,
|
||||
fp->symbol_rotation[0],
|
||||
slot,
|
||||
fp->N_RB_DL,
|
||||
|
||||
@@ -1141,9 +1141,17 @@ int main(int argc, char **argv)
|
||||
|
||||
//TODO: loop over slots
|
||||
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) {
|
||||
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],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
@@ -1154,7 +1162,14 @@ int main(int argc, char **argv)
|
||||
for (int i = 0; i < 14; i++) {
|
||||
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],
|
||||
14,
|
||||
frame_parms,
|
||||
|
||||
@@ -525,17 +525,28 @@ int main(int argc, char **argv)
|
||||
nr_common_signal_procedures (gNB,frame,slot, &ssb_pdu[i]);
|
||||
|
||||
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) {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
gNB->common_vars.txdataF[0][aa],
|
||||
true,
|
||||
frame_parms->symbol_rotation[0],
|
||||
slot,
|
||||
frame_parms->N_RB_DL,
|
||||
0,
|
||||
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],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
@@ -544,21 +555,30 @@ int main(int argc, char **argv)
|
||||
} else {
|
||||
apply_nr_rotation_TX(frame_parms,
|
||||
gNB->common_vars.txdataF[0][aa],
|
||||
true,
|
||||
frame_parms->symbol_rotation[0],
|
||||
slot,
|
||||
frame_parms->N_RB_DL,
|
||||
0,
|
||||
14);
|
||||
|
||||
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa],
|
||||
(int*)&txdata[aa][samp],
|
||||
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);
|
||||
|
||||
PHY_ofdm_mod((int *)fft_in_buff,
|
||||
(int *)&txdata[aa][samp],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples0,
|
||||
CYCLIC_PREFIX);
|
||||
|
||||
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][frame_parms->ofdm_symbol_size],
|
||||
(int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + 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],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
13,
|
||||
frame_parms->nb_prefix_samples,
|
||||
|
||||
+34
-47
@@ -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 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) {
|
||||
u8dptr = (uint8_t *)ptr;
|
||||
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)
|
||||
}
|
||||
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) {
|
||||
payload_len = numRB * N_SC_PER_PRB * 4L;
|
||||
/* convert to Network order */
|
||||
// NOTE: ggc 11 knows how to generate AVX2 for this!
|
||||
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) {
|
||||
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__)
|
||||
struct xranlib_compress_request bfp_com_req = {};
|
||||
struct xranlib_compress_response bfp_com_rsp = {};
|
||||
|
||||
uint32_t src_compr[num_totalRB * N_SC_PER_PRB] __attribute__((aligned(64)));
|
||||
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.data_in = (int16_t *)src_compr;
|
||||
|
||||
bfp_com_req.numRBs = numRB;
|
||||
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)
|
||||
|
||||
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
|
||||
#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
|
||||
AssertFatal(1 == 0, "BFP compression not supported on this architecture");
|
||||
#endif
|
||||
@@ -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_config *fh_cfg = get_xran_fh_config(0);
|
||||
int nPRBs = fh_cfg->nDLRBs;
|
||||
int fftsize = 1 << fh_cfg->nDLFftSize;
|
||||
int nb_tx_per_ru = ru->nb_tx / 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
|
||||
}
|
||||
uint16_t *dst16 = (uint16_t *)dst;
|
||||
|
||||
int pos_len = 0;
|
||||
int neg_len = 0;
|
||||
|
||||
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);
|
||||
int32_t *pos_start = pos + p_prbMapElm->UP_nRBStart * N_SC_PER_PRB;
|
||||
uint32_t numPrb = p_prbMapElm->UP_nRBSize;
|
||||
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 */
|
||||
// NOTE: ggc 11 knows how to generate AVX2 for this!
|
||||
for (idx = 0; idx < (pos_len + neg_len) * 2; idx++)
|
||||
((uint16_t *)dst16)[idx] = htons(((uint16_t *)local_src)[idx]);
|
||||
for (idx = 0; idx < numPrb * N_SC_PER_PRB * 2; idx++)
|
||||
((uint16_t *)dst16)[idx] = htons(((uint16_t *)pos_start)[idx]);
|
||||
} 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__)
|
||||
struct xranlib_compress_request bfp_com_req = {};
|
||||
struct xranlib_compress_response bfp_com_rsp = {};
|
||||
|
||||
bfp_com_req.data_in = (int16_t *)local_src;
|
||||
bfp_com_req.numRBs = p_prbMapElm->UP_nRBSize;
|
||||
bfp_com_req.data_in = (int16_t *)src_compr;
|
||||
bfp_com_req.numRBs = numPrb;
|
||||
bfp_com_req.len = payload_len;
|
||||
bfp_com_req.compMethod = p_prbMapElm->compMethod;
|
||||
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
|
||||
|
||||
xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
|
||||
#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
|
||||
AssertFatal(1 == 0, "BFP compression not supported on this architecture");
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user