mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Merge remote-tracking branch 'origin/fix-prach-diff-mu' into integration_2026_w12 (!3935)
[FHI72] Fix long PRACH format The problem was that xran_is_prach_slot() compared if the current slot is the scheduled one. However, this becomes irrelevant if long PRACH format used. Successfully tested end-to-end the PRACH index 7 with TDD DDDDDDDSUU and Benetel v2.0.5.
This commit is contained in:
@@ -178,25 +178,25 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
|
||||
nr_prach_info_t prach_info = get_prach_info(0);
|
||||
|
||||
uint16_t N_ZC, num_prbu;
|
||||
if ((prach_info.format & 0xff) < 4) {
|
||||
N_ZC = 839;
|
||||
num_prbu = 70;
|
||||
prach_info.N_dur = 1;
|
||||
} else {
|
||||
N_ZC = 139;
|
||||
num_prbu = 12;
|
||||
}
|
||||
|
||||
int prach_start_sym = prach_info.start_symbol;
|
||||
int prach_end_sym = prach_info.N_dur + prach_start_sym;
|
||||
struct xran_ru_config *ru_conf = &fh_cfg->ru_conf;
|
||||
int slots_per_frame = 10 << fh_cfg->frame_conf.nNumerology;
|
||||
int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology;
|
||||
|
||||
int tti = slots_per_frame * (frame) + (slot);
|
||||
uint32_t subframe = slot / slots_per_subframe;
|
||||
// PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4
|
||||
uint32_t is_prach_frame = (frame % prach_info.x == prach_info.y);
|
||||
uint32_t is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (slot % slots_per_subframe));
|
||||
|
||||
int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports;
|
||||
/* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */
|
||||
if (is_prach_slot) {
|
||||
if (!ru->prach_buf) {
|
||||
LOG_W(HW, "we get rach data from ru, but it is not scheduled %d.%d\n", frame, slot);
|
||||
return -1;
|
||||
}
|
||||
if (ru->prach_buf) {
|
||||
for (sym_idx = prach_start_sym; sym_idx < prach_end_sym; sym_idx++) {
|
||||
for (int aa = 0; aa < ru->nb_rx; aa++) {
|
||||
int16_t *dst, *src;
|
||||
@@ -208,25 +208,25 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
/* convert Network order to host order */
|
||||
if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_NONE) {
|
||||
if (sym_idx == prach_start_sym) {
|
||||
for (idx = 0; idx < 139 * 2; idx++) {
|
||||
for (idx = 0; idx < N_ZC * 2; idx++) {
|
||||
dst[idx] = ((int16_t)ntohs(src[idx + g_kbar]));
|
||||
}
|
||||
} else {
|
||||
for (idx = 0; idx < 139 * 2; idx++) {
|
||||
for (idx = 0; idx < N_ZC * 2; idx++) {
|
||||
dst[idx] += ((int16_t)ntohs(src[idx + g_kbar]));
|
||||
}
|
||||
}
|
||||
} else if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_BLKFLOAT) {
|
||||
|
||||
int16_t local_dst[12 * 2 * N_SC_PER_PRB] __attribute__((aligned(64)));
|
||||
int16_t local_dst[num_prbu * 2 * N_SC_PER_PRB] __attribute__((aligned(64)));
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
struct xranlib_decompress_request bfp_decom_req = {};
|
||||
struct xranlib_decompress_response bfp_decom_rsp = {};
|
||||
int payload_len = (3 * ru_conf->iqWidth_PRACH + 1) * 12; // 12 = closest number of PRBs to 139 REs
|
||||
int payload_len = (3 * ru_conf->iqWidth_PRACH + 1) * num_prbu;
|
||||
|
||||
bfp_decom_req.data_in = (int8_t *)src;
|
||||
bfp_decom_req.numRBs = 12; // closest number of PRBs to 139 REs
|
||||
bfp_decom_req.numRBs = num_prbu;
|
||||
bfp_decom_req.len = payload_len;
|
||||
bfp_decom_req.compMethod = XRAN_COMPMETHOD_BLKFLOAT;
|
||||
bfp_decom_req.iqWidth = ru_conf->iqWidth_PRACH;
|
||||
@@ -235,21 +235,20 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot)
|
||||
bfp_decom_rsp.len = 0;
|
||||
xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
armral_bfp_decompression(ru_conf->iqWidth_PRACH, 12, (int8_t *)src, (int16_t *)local_dst);
|
||||
armral_bfp_decompression(ru_conf->iqWidth_PRACH, num_prbu, (int8_t *)src, (int16_t *)local_dst);
|
||||
#else
|
||||
AssertFatal(1 == 0, "BFP decompression not supported on this architecture");
|
||||
#endif
|
||||
// note: this is hardwired for 139 point PRACH sequence, kbar=2
|
||||
if (sym_idx == prach_start_sym)
|
||||
for (idx = 0; idx < (139 * 2); idx++)
|
||||
for (idx = 0; idx < (N_ZC * 2); idx++)
|
||||
dst[idx] = local_dst[idx + g_kbar];
|
||||
else
|
||||
for (idx = 0; idx < (139 * 2); idx++)
|
||||
for (idx = 0; idx < (N_ZC * 2); idx++)
|
||||
dst[idx] += (local_dst[idx + g_kbar]);
|
||||
} // COMPMETHOD_BLKFLOAT
|
||||
} // aa
|
||||
} // symb_indx
|
||||
} // is_prach_slot
|
||||
} // ru->prach_buf
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -213,16 +213,31 @@ int trx_oran_ctlrecv(openair0_device_t *device, void *msg, ssize_t msg_len)
|
||||
|
||||
void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot)
|
||||
{
|
||||
prach_item_t *prach_id = find_nr_prach(&ru->gNB_list[0]->prach_list, *frame, *slot, SEARCH_EXIST);
|
||||
ru_info_t ru_info = {
|
||||
.nb_rx = ru->nb_rx * ru->num_beams_period,
|
||||
.nb_tx = ru->nb_tx * ru->num_beams_period,
|
||||
.rxdataF = ru->common.rxdataF,
|
||||
.beam_id = ru->common.beam_id,
|
||||
.num_beams_period = ru->num_beams_period,
|
||||
.prach_buf = prach_id ? prach_id->rxsigF : NULL,
|
||||
.prach_buf = NULL,
|
||||
};
|
||||
|
||||
prach_item_t *prach_id = find_nr_prach(&ru->gNB_list[0]->prach_list, *frame, *slot, SEARCH_EXIST);
|
||||
if (prach_id) {
|
||||
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
|
||||
int slots_per_subframe = 1 << fh_cfg->frame_conf.nNumerology;
|
||||
uint32_t subframe = *slot / slots_per_subframe; // `slot` = slot in which PRACH is received
|
||||
// PRACH occasion in a frame if and only if SFN % x == y, TS 38.211 Table 6.3.3.2-2/3/4
|
||||
nr_prach_info_t prach_info = get_prach_info(0);
|
||||
bool is_prach_frame = (*frame % prach_info.x == prach_info.y);
|
||||
bool is_prach_slot = is_prach_frame && xran_is_prach_slot(0, subframe, (prach_id->slot % slots_per_subframe)); // `prach_id->slot` = slot in which PRACH is scheduled
|
||||
if (is_prach_slot) {
|
||||
ru_info.prach_buf = prach_id->rxsigF;
|
||||
} else {
|
||||
LOG_W(HW, "[%d.%d] Expected PRACH reception of scheduled slot %d\n", *frame, *slot, prach_id->slot);
|
||||
}
|
||||
}
|
||||
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
int f, sl;
|
||||
LOG_D(HW, "Read rxdataF %p,%p\n", ru_info.rxdataF[0], ru_info.rxdataF[1]);
|
||||
|
||||
Reference in New Issue
Block a user