Merge remote-tracking branch 'origin/ue-long-prach' into integration_2025_w09
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"};
|
||||
|
||||
/*************************************
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user