Remove prach_ifft from premanent allocation

Allocate on the stack when necessary.
This commit is contained in:
Laurent THOMAS
2025-10-30 11:54:01 +01:00
committed by Robert Schmidt
parent e54738c7e4
commit 9ddb8c0b9f
3 changed files with 87 additions and 142 deletions
+1 -6
View File
@@ -190,8 +190,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
common_vars->debugBuff_sample_offset = 0;
// PRACH
prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*));
prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx * sizeof(int16_t *));
init_prach_list(gNB);
@@ -266,10 +265,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(common_vars->debugBuff);
NR_gNB_PRACH* prach_vars = &gNB->prach_vars;
free_and_zero(prach_vars->rxsigF);
free_and_zero(prach_vars->prach_ifft);
for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) {
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id];
for (int i = 0; i < n_buf; i++) {
+86 -134
View File
@@ -452,81 +452,67 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
{
AssertFatal(gNB != NULL, "Can only be called from gNB\n");
nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config;
NR_DL_FRAME_PARMS *fp;
c16_t **rxsigF = (c16_t **)gNB->prach_vars.rxsigF;
uint16_t preamble_index0 = 0;
uint16_t numshift = 0;
int first_nonzero_root_idx = 0;
bool new_dft = false;
int log2_ifft_size = 10;
uint16_t rootSequenceIndex;
int numrootSequenceIndex;
uint8_t restricted_set;
uint8_t n_ra_prb=0xFF;
int nb_rx;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
int16_t **rxsigF = gNB->prach_vars.rxsigF;
const int nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
const int rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value;
const int numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value;
const int NCS = prach_pdu->num_cs; // cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
const int prach_sequence_length = cfg->prach_sequence_length.value;
const int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value;
const int restricted_set = cfg->restricted_set_config.value;
const int prach_fmt = prach_pdu->prach_format;
const int N_ZC = prach_sequence_length == 0 ? 839 : 139;
uint8_t preamble_index;
uint16_t NCS=99,NCS2;
uint16_t preamble_offset=0,preamble_offset_old;
int16_t preamble_shift=0;
uint32_t preamble_shift2;
uint16_t preamble_index0=0,n_shift_ra=0,n_shift_ra_bar;
uint16_t d_start=0;
uint16_t numshift=0;
const uint16_t *prach_root_sequence_map;
uint8_t not_found;
uint16_t u;
int16_t *Xu=0;
uint16_t first_nonzero_root_idx=0;
uint8_t new_dft=0;
int32_t lev;
int16_t levdB;
int log2_ifft_size=10;
int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
int32_t *prach_ifft=(int32_t*)NULL;
fp = &gNB->frame_parms;
LOG_D(PHY,
"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",
rootSequenceIndex,
numrootSequenceIndex,
NCS,
N_ZC,
prach_fmt);
nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value;
numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value;
NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value;
int prach_sequence_length = cfg->prach_sequence_length.value;
int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value;
// int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value;
// cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list
restricted_set = cfg->restricted_set_config.value;
uint8_t prach_fmt = prach_pdu->prach_format;
uint16_t N_ZC = (prach_sequence_length==0)?839:139;
LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt);
prach_ifft = gNB->prach_vars.prach_ifft;
if (LOG_DEBUGFLAG(DEBUG_PRACH)) {
if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", slot, msg1_frequencystart, rootSequenceIndex);
if ((frame & 1023) < 20)
LOG_D(PHY,
"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n",
slot,
msg1_frequencystart,
rootSequenceIndex);
}
start_meas(&gNB->rx_prach);
prach_root_sequence_map = (cfg->prach_sequence_length.value==0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
const uint16_t *prach_root_sequence_map =
cfg->prach_sequence_length.value == 0 ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
// PDP is oversampled, e.g. 1024 sample instead of 839
// Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839
NCS2 = (N_ZC==839) ? ((NCS<<10)/839) : ((NCS<<8)/139);
int NCS2 = N_ZC == 839 ? (NCS << 10) / 839 : (NCS << 8) / 139;
if (NCS2==0) NCS2 = N_ZC;
if (NCS2 == 0)
NCS2 = N_ZC;
int preamble_offset = 0, preamble_offset_old = 99;
preamble_offset_old = 99;
*max_preamble_energy = 0;
*max_preamble_delay = 0;
*max_preamble = 0;
int16_t prachF[2 * 1024];
for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
int16_t preamble_shift = 0;
const int dft_sz = N_ZC == 839 ? 1024 : 256;
int32_t prach_ifft[dft_sz] __attribute__((aligned(32)));
for (int preamble_index = 0; preamble_index < 64; preamble_index++) {
if (LOG_DEBUGFLAG(DEBUG_PRACH)) {
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140));
if (en>60) LOG_D(PHY,"frame %d, slot %d : Trying preamble %d \n",frame,slot,preamble_index);
int en = dB_fixed(signal_energy((int32_t *)rxsigF[0], N_ZC == 839 ? 840 : 140));
if (en > 60)
LOG_D(PHY, "frame %d, slot %d : Trying preamble %d \n", frame, slot, preamble_index);
}
if (restricted_set == 0) {
// This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
@@ -534,48 +520,43 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
if (preamble_offset != preamble_offset_old) {
preamble_offset_old = preamble_offset;
new_dft = 1;
new_dft = true;
// This is the \nu corresponding to the preamble index
preamble_shift = 0;
}
else {
preamble_shift -= NCS;
} else {
preamble_shift -= NCS;
if (preamble_shift < 0)
preamble_shift+=N_ZC;
preamble_shift += N_ZC;
}
} else { // This is the high-speed case
new_dft = 0;
new_dft = false;
uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1];
nr_fill_du(N_ZC, prach_root_sequence_map, nr_du);
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift
// Check if all shifts for that root have been processed
int n_shift_ra = 0, n_shift_ra_bar, d_start = 0;
if (preamble_index0 == numshift) {
not_found = 1;
new_dft = 1;
bool not_found = true;
new_dft = true;
preamble_index0 -= numshift;
//(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
while (not_found == 1) {
while (not_found) {
// current root depending on rootSequenceIndex
int index = (rootSequenceIndex + preamble_offset) % N_ZC;
u = prach_root_sequence_map[index];
int u = nr_du[prach_root_sequence_map[index]];
uint16_t n_group_ra = 0;
if ((nr_du[u] < (N_ZC / 3)) && (nr_du[u] >= NCS) ) {
n_shift_ra = nr_du[u] / NCS;
d_start = (nr_du[u] << 1) + (n_shift_ra * NCS);
if (u < (N_ZC / 3) && u >= NCS) {
n_shift_ra = u / NCS;
d_start = (u << 1) + (n_shift_ra * NCS);
n_group_ra = N_ZC / d_start;
n_shift_ra_bar = max(0, (N_ZC-(nr_du[u] << 1) - (n_group_ra * d_start)) / N_ZC);
} else if ((nr_du[u] >= (N_ZC / 3)) && (nr_du[u] <= ((N_ZC - NCS) >> 1))) {
n_shift_ra = (N_ZC - (nr_du[u] << 1)) / NCS;
d_start = N_ZC - (nr_du[u] << 1) + (n_shift_ra * NCS);
n_group_ra = nr_du[u] / d_start;
n_shift_ra_bar = min(n_shift_ra, max(0, (nr_du[u]- (n_group_ra * d_start)) / NCS));
n_shift_ra_bar = max(0, (N_ZC - (u << 1) - (n_group_ra * d_start)) / N_ZC);
} else if (u >= (N_ZC / 3) && u <= ((N_ZC - NCS) >> 1)) {
n_shift_ra = (N_ZC - (u << 1)) / NCS;
d_start = N_ZC - (u << 1) + (n_shift_ra * NCS);
n_group_ra = u / d_start;
n_shift_ra_bar = min(n_shift_ra, max(0, (u - (n_group_ra * d_start)) / NCS));
} else {
n_shift_ra = 0;
n_shift_ra_bar = 0;
@@ -584,12 +565,13 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// This is the number of cyclic shifts for the current root u
numshift = (n_shift_ra * n_group_ra) + n_shift_ra_bar;
// skip to next root and recompute parameters if numshift==0
(numshift>0) ? (not_found = 0) : (preamble_offset++);
numshift > 0 ? not_found = false : preamble_offset++;
}
}
if (n_shift_ra>0)
preamble_shift = -((d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS)); // minus because the channel is h(t -\tau + Cv)
preamble_shift = -(d_start * (preamble_index0 / n_shift_ra)
+ (preamble_index0 % n_shift_ra) * NCS); // minus because the channel is h(t -\tau + Cv)
else
preamble_shift = 0;
@@ -604,7 +586,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
if (LOG_DEBUGFLAG(DEBUG_PRACH)) {
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
int en = dB_fixed(signal_energy((int32_t *)rxsigF[0], 840));
if (en>60)
LOG_D(PHY,
"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
@@ -620,42 +602,30 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset);
if (new_dft) {
new_dft = false;
if (new_dft == 1) {
new_dft = 0;
Xu = (int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx];
c16_t *Xu = (c16_t *)gNB->X_u[preamble_offset - first_nonzero_root_idx];
LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx);
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
memset(prachF, 0, sizeof(int16_t) * 2 * 1024);
memset(prach_ifft, 0, sizeof(prach_ifft));
if (LOG_DUMPFLAG(DEBUG_PRACH)) {
LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1);
LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
}
c16_t prachF[dft_sz] __attribute__((aligned(32)));
for (int aa = 0; aa < nb_rx; aa++) {
// Do componentwise product with Xu* on each antenna
for (int offset = 0; offset < (N_ZC << 1); offset += 2) {
prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15);
prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15);
// Do componentwise product with Xu* on each antenna
for (int offset = 0; offset < N_ZC; offset++) {
prachF[offset] = c16MulConjShift(Xu[offset], rxsigF[aa][offset], 15);
}
memset(prachF + N_ZC, 0, sizeof(*prachF) * (dft_sz - N_ZC));
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
if (N_ZC == 839) {
idft(IDFT_1024, prachF, prach_ifft_tmp, 1);
// compute energy and accumulate over receive antennas
for (int i = 0; i < 1024; i++)
prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
} else {
idft(IDFT_256, prachF, prach_ifft_tmp, 1);
log2_ifft_size = 8;
// compute energy and accumulate over receive antennas and repetitions for BR
for (int i = 0; i < 256; i++)
prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)];
}
c16_t prach_ifft_tmp[dft_sz] __attribute__((aligned(32)));
idft(get_idft(dft_sz), (int16_t *)prachF, (int16_t *)prach_ifft_tmp, 1);
// compute energy and accumulate over receive antennas
for (int i = 0; i < dft_sz; i++)
prach_ifft[i] += squaredMod(prach_ifft_tmp[i]);
if (LOG_DUMPFLAG(DEBUG_PRACH)) {
if (aa == 0)
@@ -678,14 +648,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
}
} // new dft
// check energy in nth time shift, for
preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<<log2_ifft_size)/N_ZC));
// check energy in nth time shift, for
int preamble_shift2 = preamble_shift == 0 ? 0 : (preamble_shift << log2_ifft_size) / N_ZC;
for (int i = 0; i < NCS2; i++) {
lev = (int32_t)prach_ifft[(preamble_shift2+i)];
levdB = dB_fixed_times10(lev);
int lev = prach_ifft[preamble_shift2 + i];
int levdB = dB_fixed_times10(lev);
if (levdB>*max_preamble_energy) {
LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy);
*max_preamble_energy = levdB;
@@ -693,8 +663,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
*max_preamble = preamble_index;
}
}
}// preamble_index
} // preamble_index
// The conversion from *max_preamble_delay from TA value is done here.
// It is normalized to the 30.72 Ms/s, considering the numerology, N_RB and the sampling rate
@@ -721,23 +690,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
}
else *TA = *TA/2;
if (LOG_DUMPFLAG(DEBUG_PRACH)) {
//int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
// if (en>60) {
int k = (12 * n_ra_prb) - 6 * fp->N_RB_UL;
if (k < 0)
k += fp->ofdm_symbol_size;
k*=12;
k+=13;
k*=2;
LOG_M("rxsigF.m","prach_rxF", &rxsigF[0][0], 12288, 1, 1);
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0", prachF, 1024, 1, 1);
LOG_M("Xu.m","xu", Xu, N_ZC, 1, 1);
LOG_M("prach_ifft0.m","prach_t0", prach_ifft, 1024, 1, 1);
// }
}
stop_meas(&gNB->rx_prach);
}
-2
View File
@@ -151,8 +151,6 @@ typedef struct {
/// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
/// third index: frequency-domain sample [0..ofdm_symbol_size*12[
int16_t **rxsigF;
/// \brief local buffer to compute prach_ifft
int32_t *prach_ifft;
gNB_PRACH_list_t list[NUMBER_OF_NR_PRACH_MAX];
} NR_gNB_PRACH;