Merge remote-tracking branch 'origin/ue-long-prach' into integration_2025_w09

This commit is contained in:
francescomani
2025-03-01 16:34:48 +01:00
29 changed files with 471 additions and 332 deletions
-1
View File
@@ -271,7 +271,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
}
ue->init_averaging = 1;
init_nr_prach_tables(839);
init_symbol_rotation(fp);
init_timeshift_rotation(fp);
+34 -38
View File
@@ -43,6 +43,7 @@ void init_prach_list(PHY_VARS_gNB *gNB)
gNB->prach_vars.list[i].frame = -1;
gNB->prach_vars.list[i].slot = -1;
gNB->prach_vars.list[i].beam_nb = -1;
gNB->prach_vars.list[i].num_slots = -1;
}
}
@@ -51,24 +52,20 @@ void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id)
gNB->prach_vars.list[prach_id].frame = -1;
gNB->prach_vars.list[prach_id].slot = -1;
gNB->prach_vars.list[prach_id].beam_nb = -1;
gNB->prach_vars.list[prach_id].num_slots = -1;
}
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) {
AssertFatal(gNB!=NULL,"gNB is null\n");
for (uint16_t i=0; i<NUMBER_OF_NR_PRACH_MAX; i++) {
LOG_D(PHY,"searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame,slot,i,
gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot);
if((type == SEARCH_EXIST_OR_FREE) &&
(gNB->prach_vars.list[i].frame == -1) &&
(gNB->prach_vars.list[i].slot == -1)) {
return i;
}
else if ((type == SEARCH_EXIST) &&
(gNB->prach_vars.list[i].frame == frame) &&
(gNB->prach_vars.list[i].slot == slot)) {
return i;
}
gNB_PRACH_list_t *p = gNB->prach_vars.list + i;
LOG_D(PHY, "searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot);
if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) {
return i;
} else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) {
return i;
}
}
return -1;
}
@@ -80,6 +77,8 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p
gNB_PRACH_list_t *prach = &gNB->prach_vars.list[prach_id];
prach->frame = SFN;
prach->slot = Slot;
const int format = prach_pdu->prach_format;
prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1;
prach->beam_nb = 0;
if (gNB->common_vars.beam_id) {
int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
@@ -98,6 +97,7 @@ void init_prach_ru_list(RU_t *ru)
for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) {
ru->prach_list[i].frame = -1;
ru->prach_list[i].slot = -1;
ru->prach_list[i].num_slots = -1;
}
pthread_mutex_init(&ru->prach_list_mutex, NULL);
}
@@ -107,16 +107,12 @@ int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type)
AssertFatal(ru != NULL, "ru is null\n");
pthread_mutex_lock(&ru->prach_list_mutex);
for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) {
LOG_D(PHY,"searching for PRACH in %d.%d : prach_index %d=> %d.%d\n",
frame,
slot,
i,
ru->prach_list[i].frame,ru->prach_list[i].slot);
if((type == SEARCH_EXIST_OR_FREE) && (ru->prach_list[i].frame == -1) && (ru->prach_list[i].slot == -1)) {
RU_PRACH_list_t *p = ru->prach_list + i;
LOG_D(PHY, "searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot);
if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) {
pthread_mutex_unlock(&ru->prach_list_mutex);
return i;
}
else if ((type == SEARCH_EXIST) && (ru->prach_list[i].frame == frame) && (ru->prach_list[i].slot == slot)) {
} else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) {
pthread_mutex_unlock(&ru->prach_list_mutex);
return i;
}
@@ -135,7 +131,9 @@ void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_p
pthread_mutex_lock(&ru->prach_list_mutex);
ru->prach_list[prach_id].frame = SFN;
ru->prach_list[prach_id].slot = Slot;
ru->prach_list[prach_id].fmt = prach_pdu->prach_format;
const int fmt = prach_pdu->prach_format;
ru->prach_list[prach_id].num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1;
ru->prach_list[prach_id].fmt = fmt;
ru->prach_list[prach_id].numRA = prach_pdu->num_ra;
ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol;
ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas;
@@ -150,8 +148,14 @@ void free_nr_ru_prach_entry(RU_t *ru, int prach_id)
pthread_mutex_unlock(&ru->prach_list_mutex);
}
void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol, int prachOccasion, int frame, int slot)
void rx_nr_prach_ru(RU_t *ru,
int prachFormat,
int numRA,
int prachStartSymbol,
int prachStartSlot,
int prachOccasion,
int frame,
int slot)
{
AssertFatal(ru != NULL,"ru is null\n");
@@ -161,6 +165,7 @@ void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol,
int16_t *prach[ru->nb_rx];
int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value;
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
const uint8_t prach_mu = ru->config.prach_config.prach_sub_c_spacing.value;
int sample_offset_slot;
if (prachStartSymbol == 0) {
@@ -193,7 +198,7 @@ void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol,
for (int aa=0; aa<ru->nb_rx; aa++){
if (prach_sequence_length == 0)
slot2 = (slot / fp->slots_per_subframe) * fp->slots_per_subframe;
slot2 = prachStartSlot;
prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset];
}
@@ -387,18 +392,9 @@ void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol,
LOG_D(PHY, "rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d dftlen:%d\n", ru->nb_rx, Ncp, dftlen);
}
// Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
int kbar = 1;
int K = 24;
if (prach_sequence_length == 0 && prachFormat == 3) {
K=4;
kbar=10;
}
else if (prach_sequence_length == 1) {
// Note: Assumes that PRACH SCS is same as PUSCH SCS
K=1;
kbar=2;
}
const unsigned int K = get_prach_K(prach_sequence_length, prachFormat, fp->numerology_index, prach_mu);
const uint8_t kbar = get_PRACH_k_bar(prach_mu, fp->numerology_index);
int n_ra_prb = msg1_frequencystart;
int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
@@ -433,7 +429,6 @@ void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol,
}
memcpy((void*)rxsigF2,(void *)rxsigF_tmp,N_ZC<<2);
}
}
void rx_nr_prach(PHY_VARS_gNB *gNB,
@@ -542,7 +537,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
}
} else { // This is the high-speed case
new_dft = 0;
nr_fill_du(N_ZC,prach_root_sequence_map);
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
-3
View File
@@ -30,9 +30,6 @@
* \warning
*/
extern c16_t nr_ru[839]; // quantized roots of unity
extern uint16_t nr_du[838];
static const char* const prachfmt[] = {"0", "1", "2", "3", "A1", "A2", "A3", "B1", "B4", "C0", "C2", "A1/B1", "A2/B2", "A3/B3"};
/*************************************
+37 -55
View File
@@ -38,12 +38,34 @@
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "T.h"
c16_t nr_ru[839]; // quantized roots of unity
static uint32_t nr_ZC_inv[839]; // multiplicative inverse for roots u
uint16_t nr_du[838];
/* Extended Euclidean Algorithm to compute modulo inverse */
static int modulo_multiplicative_inverse(const int a, const int m)
{
DevAssert(a < m);
int t = 0;
int newt = 1;
int r = m;
int newr = a;
while (newr != 0) {
const int q = r / newr;
int tmp = t;
t = newt;
newt = tmp - q * newt;
tmp = r;
r = newr;
newr = tmp - q * newr;
}
AssertFatal(r <= 1, "Modulo inverse doesn't exist for a %d, m %d\n", a, m);
t = (t < 0) ? t + m : t;
LOG_D(PHY, "Modulo %d inverse of %d is %d\n", m, a, t);
return t;
}
// This function computes the du
void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map)
void nr_fill_du(uint16_t N_ZC, const uint16_t* prach_root_sequence_map, uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1])
{
uint16_t iu,u,p;
@@ -64,19 +86,15 @@ void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map)
void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t rootSequenceIndex, c16_t X_u[64][839])
{
// Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC)
unsigned int k,inv_u,i;
int N_ZC;
const uint16_t *prach_root_sequence_map;
uint16_t u;
const uint16_t* prach_root_sequence_map;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN);
LOG_D(PHY,"compute_prach_seq: prach short sequence %x, num_sequences %d, rootSequenceIndex %d\n", short_sequence, num_sequences, rootSequenceIndex);
N_ZC = (short_sequence) ? 139 : 839;
init_nr_prach_tables(N_ZC);
N_ZC = (short_sequence) ? NR_PRACH_SEQ_LEN_S : NR_PRACH_SEQ_LEN_L;
if (short_sequence) {
// FIXME cannot be reached
@@ -87,7 +105,7 @@ void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t
LOG_D( PHY, "compute_prach_seq: done init prach_tables\n" );
for (i=0; i<num_sequences; i++) {
for (int i = 0; i < num_sequences; i++) {
int index = (rootSequenceIndex+i) % (N_ZC-1);
if (short_sequence) {
@@ -98,58 +116,22 @@ void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t
DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
}
u = prach_root_sequence_map[index];
const uint16_t u = prach_root_sequence_map[index];
LOG_D(PHY,"prach index %d => u=%d\n",index,u);
inv_u = nr_ZC_inv[u]; // multiplicative inverse of u
const int inv_u = modulo_multiplicative_inverse(u, N_ZC); // multiplicative inverse of u
// X_u[0] stores the first ZC sequence where the root u has a non-zero number of shifts
// for the unrestricted case X_u[0] is the first root indicated by the rootSequenceIndex
for (k=0; k<N_ZC; k++) {
const int zc_inv_2 = modulo_multiplicative_inverse(2, N_ZC);
for (int k = 0; k < N_ZC; k++) {
const unsigned int j = (((k * (1 + (inv_u * k))) % N_ZC) * zc_inv_2) % N_ZC;
const double w = 2 * M_PI * (double)j / N_ZC;
const c16_t ru = {.r = (int16_t)(floor(32767.0 * cos(w))), .i = (int16_t)(floor(32767.0 * sin(w)))};
// multiply by inverse of 2 (required since ru is exp[j 2\pi n])
X_u[i][k] = nr_ru[(((k * (1 + (inv_u * k))) % N_ZC) * nr_ZC_inv[2]) % N_ZC];
X_u[i][k] = ru;
}
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_OUT);
}
void init_nr_prach_tables(int N_ZC)
{
int i,m;
// Compute the modular multiplicative inverse 'iu' of u s.t. iu*u = 1 mod N_ZC
nr_ZC_inv[0] = 0;
nr_ZC_inv[1] = 1;
for (i=2; i<N_ZC; i++) {
for (m=2; m<N_ZC; m++)
if (((i*m)%N_ZC) == 1) {
nr_ZC_inv[i] = m;
break;
}
#ifdef PRACH_DEBUG
if (i<16)
printf("i %d : inv %d\n",i,nr_ZC_inv[i]);
#endif
}
// Compute quantized roots of unity
for (i=0; i<N_ZC; i++) {
nr_ru[i].r = (int16_t)(floor(32767.0 * cos(2 * M_PI * (double)i / N_ZC)));
nr_ru[i].i = (int16_t)(floor(32767.0 * sin(2 * M_PI * (double)i / N_ZC)));
#ifdef PRACH_DEBUG
if (i<16)
printf("i %d : runity %d,%d\n", i, nr_ru[i].r, nr_ru[i].i);
#endif
}
}
@@ -67,9 +67,7 @@ uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t rootSequenceIndex, c16_t X_u[64][839]);
void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map);
void init_nr_prach_tables(int N_ZC);
void nr_fill_du(uint16_t N_ZC, const uint16_t *prach_root_sequence_map, uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1]);
void nr_codeword_scrambling(uint8_t *in,
uint32_t size,
@@ -84,4 +82,5 @@ void nr_codeword_unscrambling_init(int16_t *s, uint32_t size, uint8_t q, uint32_
/**@}*/
void init_pucch2_luts(void);
void set_prach_tables(int N_ZC, c16_t** ru, uint32_t** zc_inv);
#endif
@@ -275,7 +275,8 @@ void rx_nr_prach_ru(RU_t *ru,
int prach_fmt,
int numRA,
int prachStartSymbol,
int prachOccasion,
int prachStartSlot,
int prachOccasion,
int frame,
int subframe);
+35 -41
View File
@@ -63,17 +63,17 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
const uint16_t *prach_root_sequence_map;
uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=INT16_MAX, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
c16_t prach[(4688 + 4 * 24576) * 2] __attribute__((aligned(32))) = {0};
int16_t prachF_tmp[(4688+4*24576)*4*2] __attribute__((aligned(32))) = {0};
c16_t prachF_tmp[(4688 + 4 * 24576) * 4] __attribute__((aligned(32))) = {0};
int Ncp = 0;
int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
int prach_start, prach_sequence_length, prach_len, dftlen, mu, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
fd_occasion = 0;
prach_len = 0;
dftlen = 0;
first_nonzero_root_idx = 0;
int16_t amp = ue->prach_vars[gNB_id]->amp;
int16_t *prachF = prachF_tmp;
int16_t amp = prach_pdu->prach_tx_power;
c16_t *prachF = prachF_tmp;
Mod_id = ue->Mod_id;
prach_sequence_length = nrUE_config->prach_config.prach_sequence_length;
N_ZC = (prach_sequence_length == 0) ? 839:139;
@@ -83,18 +83,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
n_ra_prb = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,//prach_pdu->freq_msg1;
NCS = prach_pdu->num_cs;
prach_fmt_id = prach_pdu->prach_format;
preamble_index = prach_pdu->ra_PreambleIndex;
kbar = 1;
K = 24;
preamble_index = prach_pdu->ra_PreambleIndex;
k = 12*n_ra_prb - 6*fp->N_RB_UL;
prachStartSymbol = prach_pdu->prach_start_symbol;
LOG_D(PHY,"Generate NR PRACH %d.%d\n", frame, slot);
compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
if (nrUE_config->prach_config.root_seq_computed == 0) {
compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
nrUE_config->prach_config.root_seq_computed = 1;
}
if (prachStartSymbol == 0) {
sample_offset_slot = 0;
@@ -137,7 +138,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
#endif
not_found = 1;
nr_fill_du(N_ZC,prach_root_sequence_map);
uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1];
nr_fill_du(N_ZC, prach_root_sequence_map, nr_du);
preamble_index0 = preamble_index;
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift
@@ -210,20 +212,14 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
// nsymb = (frame_parms->Ncp==0) ? 14:12;
// subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*slot*nsymb;
if (prach_sequence_length == 0 && prach_fmt_id == 3) {
K = 4;
kbar = 10;
} else if (prach_sequence_length == 1) {
K = 1;
kbar = 2;
}
const unsigned int K = get_prach_K(prach_sequence_length, prach_fmt_id, fp->numerology_index, mu);
const uint8_t kbar = get_PRACH_k_bar(mu, fp->numerology_index);
if (k<0)
if (k < 0)
k += fp->ofdm_symbol_size;
k *= K;
k += kbar;
k *= 2;
LOG_I(PHY,
"PRACH [UE %d] in frame.slot %d.%d, placing PRACH in position %d, Msg1/MsgA-Preamble frequency start %d (k1 %d), "
@@ -231,7 +227,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
Mod_id,
frame,
slot,
k,
k * 2,
n_ra_prb,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,
preamble_offset,
@@ -262,7 +258,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
break;
default:
AssertFatal(1==0, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id);
AssertFatal(1 == 0, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id);
break;
}
} else {
@@ -413,12 +409,14 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
if (offset2 >= N_ZC)
offset2 -= N_ZC;
const int32_t Xu_re = (Xu[offset].r * amp) >> 15;
const int32_t Xu_im = (Xu[offset].i * amp) >> 15;
prachF[k++] = (Xu_re * nr_ru[offset2].r - Xu_im * nr_ru[offset2].i) >> 15;
prachF[k++] = (Xu_im * nr_ru[offset2].r + Xu_re * nr_ru[offset2].i) >> 15;
const c16_t Xu_t = c16xmulConstShift(Xu[offset], amp, 15);
const double w = 2 * M_PI * (double)offset2 / N_ZC;
const c16_t ru = {.r = (int16_t)(floor(32767.0 * cos(w))), .i = (int16_t)(floor(32767.0 * sin(w)))};
const c16_t p = c16mulShift(Xu_t, ru, 15);
prachF[k++] = p;
if (k==dftlen) k=0;
if (k * 2 == dftlen)
k = 0;
}
#if defined (PRACH_WRITE_OUTPUT_DEBUG)
@@ -429,7 +427,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
// This is after cyclic prefix
c16_t *prach2 = prach + Ncp;
const idft_size_idx_t idft_size = get_idft(dftlen);
idft(idft_size, prachF, (int16_t *)prach, 1);
idft(idft_size, (int16_t *)prachF, (int16_t *)prach, 1);
memmove(prach2, prach, (dftlen << 2));
if (prach_sequence_length == 0) {
@@ -504,21 +502,17 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
}
}
#ifdef NR_PRACH_DEBUG
LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id,
fp->N_RB_UL,
prach_start,
prach_len);
#endif
#ifdef NR_PRACH_DEBUG
LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id, fp->N_RB_UL, prach_start, prach_len);
#endif
for (i = 0; i < prach_len; i++)
ue->common_vars.txData[0][prach_start + i] = prach[i];
memcpy(ue->common_vars.txData[0] + prach_start, prach, sizeof(c16_t) * prach_len);
#ifdef PRACH_WRITE_OUTPUT_DEBUG
LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
#endif
LOG_M("prach_tx0.m", "prachtx0", prach + (Ncp << 1), prach_len - Ncp, 1, 1);
LOG_M("Prach_txsig.m", "txs", (int16_t *)(&ue->common_vars.txdata[0][prach_start]), 2 * (prach_start + prach_len), 1, 1)
#endif
return signal_energy((int*)prach, 256);
return signal_energy((int *)prach, 256);
}
+1 -1
View File
@@ -195,6 +195,7 @@ typedef struct {
int numRA;
int prachStartSymbol;
int num_prach_ocas;
int num_slots;
} RU_PRACH_list_t;
#define NUMBER_OF_NR_RU_PRACH_MAX 8
@@ -426,7 +427,6 @@ typedef enum {
WAIT_RESYNCH = 3
} rru_cmd_t;
typedef struct RU_t_s {
/// ThreadPool for RU
tpool_t *threadPool;
+2
View File
@@ -141,6 +141,8 @@ typedef struct {
int slot;
// identifier for concurrent beams
int beam_nb;
// prach duration in slots
int num_slots;
nfapi_nr_prach_pdu_t pdu;
} gNB_PRACH_list_t;
+1
View File
@@ -298,6 +298,7 @@ typedef struct {
typedef struct {
int16_t amp;
bool active;
int num_prach_slots;
fapi_nr_ul_config_prach_pdu prach_pdu;
} NR_UE_PRACH;
+2
View File
@@ -56,6 +56,8 @@ static const uint8_t N_slot_subframe[MU_NUMBER] = {1, 2, 4, 8, 16};
#define NB_DL_DATA_TO_UL_ACK (8) /* size of table TS 38.213 Table 9.2.3-1 */
#define NR_PRACH_SEQ_LEN_L 839
#define NR_PRACH_SEQ_LEN_S 139
/***********************************************************************
*
@@ -51,7 +51,8 @@
FN(ULSCH_RATE_MATCHING_STATS),\
FN(ULSCH_INTERLEAVING_STATS),\
FN(ULSCH_ENCODING_STATS),\
FN(OFDM_MOD_STATS)
FN(OFDM_MOD_STATS),\
FN(PRACH_GEN_STATS)
typedef enum {
FOREACH_NR_PHY_CPU_MEAS(NOOP),
+6 -5
View File
@@ -111,11 +111,11 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
ru=gNB->RU_list[0];
int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST);
if (prach_id>=0) {
int prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST);
if (prach_id >= 0) {
LOG_D(NR_PHY,"%d.%d Got prach entry id %d\n",frame,slot,prach_id);
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
const int prach_start_slot = gNB->prach_vars.list[prach_id].slot;
uint8_t prachStartSymbol;
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
@@ -151,7 +151,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
"[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol "
"%u freq index %u\n",
frame,
slot,
prach_start_slot,
max_preamble[0],
max_preamble_energy[0] / 10,
max_preamble_energy[0] % 10,
@@ -187,6 +187,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
} //if prach_id>0
} //for NUMBER_OF_NR_PRACH_OCCASION_MAX
rach_ind->slot = prach_start_slot;
} // for NUMBER_OF_NR_PRACH_OCCASION_MAX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
}
+57 -31
View File
@@ -294,14 +294,19 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
pucch_procedures_ue_nr(ue, proc, phy_data, (c16_t **)&txdataF);
LOG_D(PHY, "Sending Uplink data \n");
start_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
nr_ue_pusch_common_procedures(ue,
proc->nr_slot_tx,
&ue->frame_parms,
ue->frame_parms.nb_antennas_tx,
(c16_t **)txdataF,
link_type_ul);
stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
// Don't do OFDM Mod if txdata contains prach
const NR_UE_PRACH *prach_var = ue->prach_vars[proc->gNB_id];
if (!prach_var->active) {
start_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
nr_ue_pusch_common_procedures(ue,
proc->nr_slot_tx,
&ue->frame_parms,
ue->frame_parms.nb_antennas_tx,
(c16_t **)txdataF,
link_type_ul);
stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
}
nr_ue_prach_procedures(ue, proc);
@@ -1168,36 +1173,57 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
if (ue->prach_vars[gNB_id]->active) {
fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power;
NR_UE_PRACH *prach_var = ue->prach_vars[gNB_id];
if (prach_var->active) {
fapi_nr_ul_config_prach_pdu *prach_pdu = &prach_var->prach_pdu;
// Generate PRACH in first slot. For L839, the following slots are also filled in this slot.
if (prach_pdu->prach_slot == nr_slot_tx) {
ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power;
LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, P0_PRACH %d)\n",
__FUNCTION__,
mod_id,
frame_tx,
nr_slot_tx,
prach_pdu->ra_PreambleIndex,
ue->tx_power_dBm[nr_slot_tx]);
LOG_D(PHY,
"In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, P0_PRACH %d)\n",
__FUNCTION__,
mod_id,
frame_tx,
nr_slot_tx,
prach_pdu->ra_PreambleIndex,
ue->tx_power_dBm[nr_slot_tx]);
ue->prach_vars[gNB_id]->amp = AMP;
prach_var->amp = AMP;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
prach_power = generate_nr_prach(ue, gNB_id, frame_tx, nr_slot_tx);
start_meas_nr_ue_phy(ue, PRACH_GEN_STATS);
prach_power = generate_nr_prach(ue, gNB_id, frame_tx, nr_slot_tx);
stop_meas_nr_ue_phy(ue, PRACH_GEN_STATS);
if (cpumeas(CPUMEAS_GETSTATE)) {
LOG_D(PHY,
"[SFN %d.%d] PRACH Proc %5.2f\n",
proc->frame_tx,
proc->nr_slot_tx,
ue->phy_cpu_stats.cpu_time_stats[PRACH_GEN_STATS].p_time / (cpuf * 1000.0));
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generated PRACH Msg1 (TX power PRACH %d dBm, digital power %d dBW (amp %d)\n",
__FUNCTION__,
mod_id,
frame_tx,
nr_slot_tx,
ue->tx_power_dBm[nr_slot_tx],
dB_fixed(prach_power),
ue->prach_vars[gNB_id]->amp);
LOG_D(PHY,
"In %s: [UE %d][RAPROC][%d.%d]: Generated PRACH Msg1 (TX power PRACH %d dBm, digital power %d dBW (amp %d)\n",
__FUNCTION__,
mod_id,
frame_tx,
nr_slot_tx,
ue->tx_power_dBm[nr_slot_tx],
dB_fixed(prach_power),
ue->prach_vars[gNB_id]->amp);
ue->prach_vars[gNB_id]->active = false;
// set duration of prach slots so we know when to skip OFDM modulation
const int prach_format = ue->prach_vars[gNB_id]->prach_pdu.prach_format;
const int prach_slots = (prach_format < 4) ? get_long_prach_dur(prach_format, ue->frame_parms.numerology_index) : 1;
prach_var->num_prach_slots = prach_slots;
}
// set as inactive in the last slot
prach_var->active = !(nr_slot_tx == (prach_pdu->prach_slot + prach_var->num_prach_slots - 1));
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
+3 -2
View File
@@ -562,6 +562,7 @@ int main(int argc, char **argv){
prach_config->num_prach_fd_occasions_list[fd_occasion].k1.value = msg1_frequencystart;
prach_config->restricted_set_config.value = restrictedSetConfig;
prach_config->prach_sequence_length.value = prach_sequence_length;
prach_config->prach_sub_c_spacing.value = mu;
prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs));
prach_pdu->prach_format = prach_format;
@@ -593,7 +594,7 @@ int main(int argc, char **argv){
ue_prach_config = &UE->nrUE_config.prach_config;
txdata = UE->common_vars.txData;
UE->prach_vars[0]->amp = AMP;
ue_prach_pdu->prach_tx_power = AMP;
ue_prach_pdu->root_seq_id = rootSequenceIndex;
ue_prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig);
ue_prach_pdu->restricted_set = restrictedSetConfig;
@@ -774,7 +775,7 @@ int main(int argc, char **argv){
}
}
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot);
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, slot, prachOccasion, frame, slot);
for (int i = 0; i < ru->nb_rx; ++i)
gNB->prach_vars.rxsigF[i] = ru->prach_rxsigF[prachOccasion][i];