Commit 043da0c4 authored by Sakthivel Velumani's avatar Sakthivel Velumani

NR UE scan for SSB within current bandwidth

Till this commit, the UE gets the position of SSB in frequency from
command line and does the syncronization by locating the SSB in time. It
does this by generating a PSS time signal during initialization with the
SSB offset given via command line. Then PSS detection is done by
correlation.

In this commit, the UE computes a list of GSCN in the current NR band
that falls within the current bandwidth for the set center frequency.
For each GSCN in the list, the UE starts a thread and performs the
following:
1. Generate PSS time signal with SSB offset for current GSCN.
2. Detect PSS, SSS and decode PBCH (this step remains the same).
After all threads finishes, the results are collected.

For now, only the first detected PBCH is used to proceed further. So
this PBCH is indicated to MAC and UE exits initial sync.

Future work: The cell search can be standalone feature where the UE
could scan for SSB in the entire NR band. This would require changing
radio's frequency on the fly as the UE's bandwidth would not cover an
entire NR band. The cell detection can futher be imporved by looking
for SIB1 for each decoded PBCH.
parent 08200783
...@@ -182,6 +182,123 @@ const nr_bandentry_t nr_bandtable[] = { ...@@ -182,6 +182,123 @@ const nr_bandentry_t nr_bandtable[] = {
{261,27500040,28350000,27500040,28350000, 2,2070833, 120} {261,27500040,28350000,27500040,28350000, 2,2070833, 120}
}; };
// synchronization raster per band tables (Rel.15)
// (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1)
// band nb, sub-carrier spacing index, Range of gscn (First, Step size, Last)
// clang-format off
const sync_raster_t sync_raster[] = {
{1, 0, 5279, 1, 5419},
{2, 0, 4829, 1, 4969},
{3, 0, 4517, 1, 4693},
{5, 0, 2177, 1, 2230},
{5, 1, 2183, 1, 2224},
{7, 0, 6554, 1, 6718},
{8, 0, 2318, 1, 2395},
{12, 0, 1828, 1, 1858},
{13, 0, 1871, 1, 1885},
{14, 0, 1901, 1, 1915},
{18, 0, 2156, 1, 2182},
{20, 0, 1982, 1, 2047},
{24, 0, 3818, 1, 3892},
{24, 1, 3824, 1, 3886},
{25, 0, 4829, 1, 4981},
{26, 0, 2153, 1, 2230},
{28, 0, 1901, 1, 2002},
{29, 0, 1798, 1, 1813},
{30, 0, 5879, 1, 5893},
{34, 0, 5030, 1, 5056},
{34, 1, 5036, 1, 5050},
{38, 0, 6431, 1, 6544},
{38, 1, 6437, 1, 6538},
{39, 0, 4706, 1, 4795},
{39, 1, 4712, 1, 4789},
{40, 1, 5762, 1, 5989},
{41, 0, 6246, 3, 6717},
{41, 1, 6252, 3, 6714},
{48, 1, 7884, 1, 7982},
{50, 0, 3584, 1, 3787},
{51, 0, 3572, 1, 3574},
{53, 0, 6215, 1, 6232},
{53, 1, 6221, 1, 6226},
{65, 0, 5279, 1, 5494},
{66, 0, 5279, 1, 5494},
{66, 1, 5285, 1, 5488},
{67, 0, 1850, 1, 1888},
{70, 0, 4993, 1, 5044},
{71, 0, 1547, 1, 1624},
{74, 0, 3692, 1, 3790},
{75, 0, 3584, 1, 3787},
{76, 0, 3572, 1, 3574},
{77, 1, 7711, 1, 8329},
{78, 1, 7711, 1, 8051},
{79, 1, 8480, 16, 8880},
{85, 0, 1826, 1, 1858},
{90, 1, 6252, 1, 6714},
{91, 0, 3572, 1, 3574},
{92, 0, 3584, 1, 3787},
{93, 0, 3572, 1, 3574},
{94, 0, 3584, 1, 3587},
{257, 3, 22388, 1, 22558},
{257, 4, 22390, 2, 22556},
{258, 3, 22257, 1, 22443},
{258, 4, 22258, 2, 22442},
{260, 3, 22995, 1, 23166},
{260, 4, 22996, 2, 23164},
{261, 3, 22446, 1, 22492},
{261, 4, 22446, 2, 22490},
};
// clang-format on
// Section 5.4.3 of 38.101-1 and -2
void check_ssb_raster(uint64_t freq, int band, int scs)
{
int start_gscn = 0, step_gscn = 0, end_gscn = 0;
for (int i = 0; i < sizeof(sync_raster) / sizeof(sync_raster_t); i++) {
if (sync_raster[i].band == band && sync_raster[i].scs_index == scs) {
start_gscn = sync_raster[i].first_gscn;
step_gscn = sync_raster[i].step_gscn;
end_gscn = sync_raster[i].last_gscn;
break;
}
}
AssertFatal(start_gscn != 0, "Couldn't find band %d with SCS %d\n", band, scs);
int gscn;
if (freq < 3000000000) {
int N = 0;
int M = 0;
for (int k = 0; k < 3; k++) {
M = (k << 1) + 1;
if ((freq - M * 50000) % 1200000 == 0) {
N = (freq - M * 50000) / 1200000;
break;
}
}
AssertFatal(N != 0, "SSB frequency %lu Hz not on the synchronization raster (N * 1200kHz + M * 50 kHz)\n", freq);
gscn = (3 * N) + (M - 3) / 2;
} else if (freq < 24250000000) {
AssertFatal((freq - 3000000000) % 1440000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (3000 MHz + N * 1.44 MHz)\n",
freq);
gscn = ((freq - 3000000000) / 1440000) + 7499;
} else {
AssertFatal((freq - 24250080000) % 17280000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (24250.08 MHz + N * 17.28 MHz)\n",
freq);
gscn = ((freq - 24250080000) / 17280000) + 22256;
}
AssertFatal(gscn >= start_gscn && gscn <= end_gscn,
"GSCN %d corresponding to SSB frequency %lu does not belong to GSCN range for band %d\n",
gscn,
freq,
band);
int rel_gscn = gscn - start_gscn;
AssertFatal(rel_gscn % step_gscn == 0,
"GSCN %d corresponding to SSB frequency %lu not in accordance with GSCN step for band %d\n",
gscn,
freq,
band);
}
int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb) int get_supported_bw_mhz(frequency_range_t frequency_range, int scs, int nb_rb)
{ {
int bw_index = get_supported_band_index(scs, frequency_range, nb_rb); int bw_index = get_supported_band_index(scs, frequency_range, nb_rb);
...@@ -910,6 +1027,129 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, ...@@ -910,6 +1027,129 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
return ssb_offset_point_a; return ssb_offset_point_a;
} }
static double get_start_freq(const double fc, const int nbRB, const int mu)
{
const int scs = MU_SCS(mu) * 1000;
return fc - (nbRB / 2 * NR_NB_SC_PER_RB * scs);
}
static double get_stop_freq(const double fc, const int nbRB, const int mu)
{
int scs = MU_SCS(mu) * 1000;
return fc + (nbRB / 2 * NR_NB_SC_PER_RB * scs);
}
static void compute_M_and_N(const int gscn, int *rM, int *rN)
{
if (gscn > 1 && gscn < 7499) {
for (int M = 1; M < 6; M += 2) {
/* GSCN = 3N + (M-3) / 2
N(int) = 2 * GSCN + 3 - M
*/
if (((2 * gscn + 3 - M) % 6) == 0) {
*rM = M;
*rN = (2 * gscn + 3 - M) / 6;
break;
}
}
} else if (gscn > 7498 && gscn < 22256) {
*rN = gscn - 7499;
} else if (gscn > 22255 && gscn < 26638) {
*rN = gscn - 22256;
} else {
LOG_E(NR_PHY, "Invalid GSCN\n");
abort();
}
}
// Section 5.4.3 of 38.101-1 and -2
static double get_ssref_from_gscn(const int gscn)
{
int M, N = -1;
compute_M_and_N(gscn, &M, &N);
if (gscn > 1 && gscn < 7499) { // Sub 3GHz
AssertFatal(N > 0 && N < 2500, "Invalid N\n");
AssertFatal(M > 0 && M < 6 && (M & 0x1), "Invalid M\n");
return (N * 1200e3 + M * 50e3);
} else if (gscn > 7498 && gscn < 22256) {
AssertFatal(N > -1 && N < 14757, "Invalid N\n");
return (3000e6 + N * 1.44e6);
} else if (gscn > 22255 && gscn < 26638) {
AssertFatal(N > -1 && N < 4382, "Invalid N\n");
return (24250.08e6 + N * 17.28e6);
} else {
LOG_E(NR_PHY, "Invalid GSCN\n");
abort();
}
}
static void find_gscn_to_scan(const double startFreq,
const double stopFreq,
const sync_raster_t gscn,
int *scanGscnStart,
int *scanGscnStop)
{
const double scs = MU_SCS(gscn.scs_index) * 1e3;
const double ssbBW = 20 * NR_NB_SC_PER_RB * scs;
for (int g = gscn.first_gscn; g < gscn.last_gscn; g += gscn.step_gscn) {
const double centerSSBFreq = get_ssref_from_gscn(g);
const double startSSBFreq = centerSSBFreq - ssbBW / 2;
if (startSSBFreq < startFreq)
continue;
*scanGscnStart = g;
break;
}
for (int g = gscn.last_gscn; g > gscn.first_gscn; g -= gscn.step_gscn) {
const double centerSSBFreq = get_ssref_from_gscn(g);
const double stopSSBFreq = centerSSBFreq + ssbBW / 2 - 1;
if (stopSSBFreq > stopFreq)
continue;
*scanGscnStop = g;
break;
}
}
static int get_ssb_first_sc(const double pointA, const double ssbCenter, const int mu)
{
const double scs = MU_SCS(mu) * 1e3;
const int ssbRBs = 20;
return (int)((ssbCenter - pointA) / scs - (ssbRBs / 2 * NR_NB_SC_PER_RB));
}
/* Returns array of first SCS offset in the scanning window */
int get_scan_ssb_first_sc(const double fc, const int nbRB, const int nrBand, const int mu, nr_gscn_info_t ssbInfo[MAX_GSCN_BAND])
{
const double startFreq = get_start_freq(fc, nbRB, mu);
const double stopFreq = get_stop_freq(fc, nbRB, mu);
int scanGscnStart = -1;
int scanGscnStop = -1;
sync_raster_t tmpRaster = {0};
for (const sync_raster_t *r = sync_raster; r < r + (sizeof(sync_raster) / sizeof(sync_raster_t)); r++) {
if (r->band == nrBand && r->scs_index == mu) {
tmpRaster = *r;
break;
}
}
find_gscn_to_scan(startFreq, stopFreq, tmpRaster, &scanGscnStart, &scanGscnStop);
const double scs = MU_SCS(mu) * 1e3;
const double pointA = fc - (nbRB / 2 * scs * NR_NB_SC_PER_RB);
int numGscn = 0;
for (int g = scanGscnStart; (g <= scanGscnStop) && (numGscn < MAX_GSCN_BAND); g += tmpRaster.step_gscn) {
ssbInfo[numGscn].ssRef = get_ssref_from_gscn(g);
ssbInfo[numGscn].ssbFirstSC = get_ssb_first_sc(pointA, ssbInfo[numGscn].ssRef, mu);
ssbInfo[numGscn].gscn = g;
numGscn++;
}
return numGscn;
}
int get_delay_idx(int delay, int max_delay_comp) int get_delay_idx(int delay, int max_delay_comp)
{ {
int delay_idx = max_delay_comp + delay; int delay_idx = max_delay_comp + delay;
......
...@@ -77,6 +77,9 @@ static inline const char *rnti_types(nr_rnti_type_t rr) ...@@ -77,6 +77,9 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
} }
#undef R #undef R
#define MU_SCS(m) (15 << m)
#define MAX_GSCN_BAND 620 // n78 has the highest GSCN range of 619
#define NR_MAX_NB_LAYERS 4 // 8 #define NR_MAX_NB_LAYERS 4 // 8
typedef struct nr_bandentry_s { typedef struct nr_bandentry_s {
...@@ -98,6 +101,12 @@ typedef struct { ...@@ -98,6 +101,12 @@ typedef struct {
int last_gscn; int last_gscn;
} sync_raster_t; } sync_raster_t;
typedef struct {
int gscn;
double ssRef;
int ssbFirstSC;
} nr_gscn_info_t;
typedef enum frequency_range_e { typedef enum frequency_range_e {
FR1 = 0, FR1 = 0,
FR2 FR2
...@@ -232,6 +241,14 @@ void freq2time(uint16_t ofdm_symbol_size, ...@@ -232,6 +241,14 @@ void freq2time(uint16_t ofdm_symbol_size,
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay); void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay);
int get_scan_ssb_first_sc(const double fc,
const int nbRB,
const int nrBand,
const int mu,
nr_gscn_info_t ssbStartSC[MAX_GSCN_BAND]);
void check_ssb_raster(uint64_t freq, int band, int scs);
#define CEILIDIV(a,b) ((a+b-1)/b) #define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
......
...@@ -706,7 +706,6 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) { ...@@ -706,7 +706,6 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
void phy_term_nr_top(void) void phy_term_nr_top(void)
{ {
free_ul_reference_signal_sequences(); free_ul_reference_signal_sequences();
free_context_synchro_nr();
} }
static void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id) static void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE, struct complex16 *modulated_dmrs_sym, uint16_t slss_id)
......
...@@ -109,9 +109,8 @@ void set_Lmax(NR_DL_FRAME_PARMS *fp) { ...@@ -109,9 +109,8 @@ void set_Lmax(NR_DL_FRAME_PARMS *fp) {
} }
} }
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb)
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) { {
int mu = fp->numerology_index; int mu = fp->numerology_index;
int symbol = 0; int symbol = 0;
uint8_t n, n_temp; uint8_t n, n_temp;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb); int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band); void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
......
...@@ -61,12 +61,11 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -61,12 +61,11 @@ int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
uint32_t sample_offset, uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]); c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]);
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, int nr_slot_fep_init_sync(const NR_DL_FRAME_PARMS *frame_parms,
const UE_nr_rxtx_proc_t *proc,
unsigned char symbol, unsigned char symbol,
int sample_offset, int sample_offset,
bool pbch_decoded, const c16_t **rxdata,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
int link_type); int link_type);
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
......
...@@ -203,31 +203,19 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -203,31 +203,19 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
return 0; return 0;
} }
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, int nr_slot_fep_init_sync(const NR_DL_FRAME_PARMS *frame_parms,
const UE_nr_rxtx_proc_t *proc,
unsigned char symbol, unsigned char symbol,
int sample_offset, int sample_offset,
bool pbch_decoded, const c16_t **rxdata,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
int link_type) int link_type)
{ {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int Ns = 0;
NR_UE_COMMON *common_vars = &ue->common_vars;
int Ns = proc->nr_slot_rx;
AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
unsigned int nb_prefix_samples; unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples;
unsigned int nb_prefix_samples0;
if (pbch_decoded) {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
}
else {
nb_prefix_samples = frame_parms->nb_prefix_samples;
nb_prefix_samples0 = frame_parms->nb_prefix_samples;
}
unsigned int frame_length_samples = frame_parms->samples_per_frame; unsigned int frame_length_samples = frame_parms->samples_per_frame;
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
...@@ -236,10 +224,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, ...@@ -236,10 +224,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int rx_offset = sample_offset + slot_offset; unsigned int rx_offset = sample_offset + slot_offset;
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; rx_offset += (frame_parms->ofdm_symbol_size + nb_prefix_samples) * symbol + nb_prefix_samples;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_parms->ofdm_symbol_size * symbol;
#ifdef DEBUG_FEP #ifdef DEBUG_FEP
// if (ue->frame <100) // if (ue->frame <100)
...@@ -256,38 +241,29 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, ...@@ -256,38 +241,29 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
// rxdata is 2 frames len // rxdata is 2 frames len
// we have to wrap on the end // we have to wrap on the end
memcpy((void *)&tmp_dft_in[0], memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], (frame_length_samples * 2 - rx_offset) * sizeof(int32_t));
(void *)&common_vars->rxdata[aa][rx_offset], memcpy((void *)&tmp_dft_in[frame_length_samples * 2 - rx_offset],
(frame_length_samples*2 - rx_offset) * sizeof(int32_t)); (void *)&rxdata[aa][0],
memcpy((void *)&tmp_dft_in[frame_length_samples*2 - rx_offset], (frame_parms->ofdm_symbol_size - (frame_length_samples * 2 - rx_offset)) * sizeof(int32_t));
(void *)&common_vars->rxdata[aa][0],
(frame_parms->ofdm_symbol_size - (frame_length_samples*2 - rx_offset)) * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in; rxdata_ptr = (int16_t *)tmp_dft_in;
} else if ((rx_offset & 7) != 0) { } else if ((rx_offset & 7) != 0) {
// if input to dft is not 256-bit aligned // if input to dft is not 256-bit aligned
memcpy((void *)&tmp_dft_in[0], memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t));
(void *)&common_vars->rxdata[aa][rx_offset],
frame_parms->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in; rxdata_ptr = (int16_t *)tmp_dft_in;
} else { } else {
// use dft input from RX buffer directly // use dft input from RX buffer directly
rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; rxdata_ptr = (int16_t *)&rxdata[aa][rx_offset];
} }
start_meas(&ue->rx_dft_stats);
dft(dftsize, dft(dftsize,
rxdata_ptr, rxdata_ptr,
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], (int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1); 1);
stop_meas(&ue->rx_dft_stats);
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset]; c16_t rot2 = frame_parms->symbol_rotation[link_type][symbol + symb_offset];
rot2.i=-rot2.i; rot2.i=-rot2.i;
......
...@@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue, ...@@ -202,7 +202,7 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
return(0); return(0);
} }
void nr_pbch_dmrs_rx(int symbol, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink) void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink)
{ {
int m,m0,m1; int m,m0,m1;
uint8_t idx=0; uint8_t idx=0;
......
...@@ -21,15 +21,13 @@ ...@@ -21,15 +21,13 @@
#include "refsig_defs_ue.h" #include "refsig_defs_ue.h"
void nr_gold_pbch(PHY_VARS_NR_UE* ue) void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax)
{ {
unsigned int n = 0, x1 = 0, x2 = 0; unsigned int n = 0, x1 = 0, x2 = 0;
unsigned int Nid, i_ssb, i_ssb2; unsigned int i_ssb, i_ssb2;
unsigned char Lmax, l, n_hf, N_hf; unsigned char l, n_hf, N_hf;
uint8_t reset; uint8_t reset;
Nid = ue->frame_parms.Nid_cell;
Lmax = ue->frame_parms.Lmax;
N_hf = (Lmax == 4)? 2:1; N_hf = (Lmax == 4)? 2:1;
for (n_hf = 0; n_hf < N_hf; n_hf++) { for (n_hf = 0; n_hf < N_hf; n_hf++) {
...@@ -42,7 +40,7 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue) ...@@ -42,7 +40,7 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3); x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) { for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
ue->nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset); nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
......
...@@ -76,8 +76,15 @@ ...@@ -76,8 +76,15 @@
#define SYNCF_TMP_SIZE (SYNCHRO_FFT_SIZE_MAX*IQ_SIZE) #define SYNCF_TMP_SIZE (SYNCHRO_FFT_SIZE_MAX*IQ_SIZE)
void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue); void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue);
void free_context_synchro_nr(void); int pss_synchro_nr(const c16_t **rxdata,
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change); const NR_DL_FRAME_PARMS *frame_parms,
const c16_t pssTime[NUMBER_PSS_SEQUENCE][frame_parms->ofdm_symbol_size],
int is,
bool fo_flag,
int target_Nid_cell,
int *nid2,
int *f_off);
void generate_pss_nr_time(const NR_DL_FRAME_PARMS *fp, const int N_ID_2, int ssbFirstSCS, c16_t pssTime[fp->ofdm_symbol_size]);
int16_t *get_primary_synchro_nr2(const int nid2); int16_t *get_primary_synchro_nr2(const int nid2);
#endif /* PSS_NR_H */ #endif /* PSS_NR_H */
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
*/ */
void nr_pbch_dmrs_rx(int dmrss, unsigned int *nr_gold_pbch, c16_t *output, bool sidelink); void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
...@@ -51,7 +51,7 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, ...@@ -51,7 +51,7 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue,
unsigned short nb_pdsch_rb, unsigned short nb_pdsch_rb,
uint8_t config_type); uint8_t config_type);
void nr_gold_pbch(PHY_VARS_NR_UE* ue); void nr_gold_pbch(uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD], int Nid, int Lmax);
void nr_gold_pdcch(PHY_VARS_NR_UE* ue, void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
unsigned short n_idDMRS); unsigned short n_idDMRS);
......
...@@ -95,11 +95,15 @@ void free_context_sss_nr(void); ...@@ -95,11 +95,15 @@ void free_context_sss_nr(void);
void insert_sss_nr(int16_t *sss_time, void insert_sss_nr(int16_t *sss_time,
NR_DL_FRAME_PARMS *frame_parms); NR_DL_FRAME_PARMS *frame_parms);
bool rx_sss_nr(PHY_VARS_NR_UE *ue, bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
const UE_nr_rxtx_proc_t *proc, int nid2,
int target_Nid_cell,
int freq_offset_pss,
int ssb_start_subcarrier,
int *Nid_cell,
int32_t *tot_metric, int32_t *tot_metric,
uint8_t *phase_max, uint8_t *phase_max,
int *freq_offset_sss, int *freq_offset_sss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); c16_t rxdataF[][frame_parms->samples_per_slot_wCP]);
#endif /* SSS_NR_H */ #endif /* SSS_NR_H */
...@@ -555,21 +555,24 @@ int nr_prs_channel_estimation(uint8_t gNB_id, ...@@ -555,21 +555,24 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
return(0); return(0);
} }
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
const int symbol, const int symbol,
const int dmrss, const int dmrss,
const int Nid_cell,
const int ssb_start_subcarrier,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD], const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) const c16_t rxdataF[][fp->samples_per_slot_wCP])
{ {
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; if (ssb_offset >= fp->ofdm_symbol_size)
ssb_offset -= fp->ofdm_symbol_size;
int symbol_offset = ue->frame_parms.ofdm_symbol_size * symbol; int symbol_offset = fp->ofdm_symbol_size * symbol;
unsigned int k = ue->frame_parms.Nid_cell % 4; unsigned int k = Nid_cell % 4;
DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%u symbol %d\n", DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%u symbol %d\n",
proc->gNB_id, proc->gNB_id,
...@@ -583,8 +586,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, ...@@ -583,8 +586,7 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
c16_t pilot[200] __attribute__((aligned(16))); c16_t pilot[200] __attribute__((aligned(16)));
nr_pbch_dmrs_rx(dmrss, (uint32_t *)nr_gold_pbch, pilot, false); nr_pbch_dmrs_rx(dmrss, (uint32_t *)nr_gold_pbch, pilot, false);
c32_t computed_val = {0}; c32_t computed_val = {0};
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
int re_offset = ssb_offset; int re_offset = ssb_offset;
c16_t *pil = pilot; c16_t *pil = pilot;
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
...@@ -599,49 +601,50 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, ...@@ -599,49 +601,50 @@ c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue,
DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) { for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS) // in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) { if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48; pilot_cnt=48;
re_offset = (re_offset + 144) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 144) % fp->ofdm_symbol_size;
} }
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15); computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i); DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++; pil++;
re_offset = (re_offset + 4) % ue->frame_parms.ofdm_symbol_size; re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
} }
} }
return computed_val; return computed_val;
} }
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
NR_DL_FRAME_PARMS *fp, const sl_nr_ue_phy_params_t *sl_phy_params,
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
int estimateSz, int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
...@@ -650,7 +653,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -650,7 +653,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int dmrss, int dmrss,
uint8_t ssb_index, uint8_t ssb_index,
uint8_t n_hf, uint8_t n_hf,
c16_t rxdataF[][fp->samples_per_slot_wCP], int ssb_start_subcarrier,
const c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink, bool sidelink,
uint16_t Nid) uint16_t Nid)
{ {
...@@ -659,13 +663,11 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -659,13 +663,11 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
//int slot_pbch; //int slot_pbch;
uint8_t nushift = 0, lastsymbol = 0, num_rbs = 0; uint8_t nushift = 0, lastsymbol = 0, num_rbs = 0;
uint32_t *gold_seq = NULL; const uint32_t *gold_seq = NULL;
if (sidelink) { if (sidelink) {
AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), "symbol %d is illegal for PSBCH DM-RS \n", dmrss); AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12), "symbol %d is illegal for PSBCH DM-RS \n", dmrss);
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
LOG_D(PHY, "PSBCH Channel Estimation SLSSID:%d\n", Nid); LOG_D(PHY, "PSBCH Channel Estimation SLSSID:%d\n", Nid);
gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid]; gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid];
...@@ -673,16 +675,16 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -673,16 +675,16 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL; num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL;
} else { } else {
nushift = fp->Nid_cell % 4; nushift = Nid % 4;
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss); AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
gold_seq = ue->nr_gold_pbch[n_hf][ssb_index]; gold_seq = nr_gold_pbch[n_hf][ssb_index];
lastsymbol = 2; lastsymbol = 2;
num_rbs = 20; num_rbs = 20;
} }
unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier; unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
if (ssb_offset >= fp->ofdm_symbol_size) if (ssb_offset >= fp->ofdm_symbol_size)
ssb_offset -= fp->ofdm_symbol_size; ssb_offset -= fp->ofdm_symbol_size;
...@@ -739,7 +741,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -739,7 +741,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
int re_offset = ssb_offset; int re_offset = ssb_offset;
c16_t *pil = pilot; c16_t *pil = pilot;
c16_t *rxF = &rxdataF[aarx][symbol_offset + k]; const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset]; c16_t *dl_ch = &dl_ch_estimates[aarx][ch_offset];
memset(dl_ch, 0, sizeof(c16_t) * fp->ofdm_symbol_size); memset(dl_ch, 0, sizeof(c16_t) * fp->ofdm_symbol_size);
...@@ -824,15 +826,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -824,15 +826,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
{ {
// do ifft of channel estimate // do ifft of channel estimate
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset); LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
freq2time(ue->frame_parms.ofdm_symbol_size, freq2time(fp->ofdm_symbol_size, (int16_t *)&dl_ch_estimates[aarx][ch_offset], (int16_t *)&dl_ch_estimates_time[aarx]);
(int16_t *)&dl_ch_estimates[aarx][ch_offset],
(int16_t *)&dl_ch_estimates_time[aarx]);
} }
} }
if (!sidelink && dmrss == lastsymbol)
UEscopeCopy(ue, pbchDlChEstimateTime, (void *)dl_ch_estimates_time, sizeof(c16_t), fp->nb_antennas_rx, fp->ofdm_symbol_size, 0);
return(0); return(0);
} }
......
...@@ -57,15 +57,18 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -57,15 +57,18 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t pdcch_dl_ch_estimates[][pdcch_est_size], c16_t pdcch_dl_ch_estimates[][pdcch_est_size],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c32_t nr_pbch_dmrs_correlation(const PHY_VARS_NR_UE *ue, c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
const int symbol, const int symbol,
const int dmrss, const int dmrss,
const int Nid_cell,
const int ssb_start_subcarrier,
const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD], const uint32_t nr_gold_pbch[NR_PBCH_DMRS_LENGTH_DWORD],
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); const c16_t rxdataF[][fp->samples_per_slot_wCP]);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
NR_DL_FRAME_PARMS *fp, const sl_nr_ue_phy_params_t *sl_phy_params,
const uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD],
int estimateSz, int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size], struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
...@@ -74,7 +77,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, ...@@ -74,7 +77,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int dmrss, int dmrss,
uint8_t ssb_index, uint8_t ssb_index,
uint8_t n_hf, uint8_t n_hf,
c16_t rxdataF[][fp->samples_per_slot_wCP], int ssb_start_subcarrier,
const c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink, bool sidelink,
uint16_t Nid); uint16_t Nid);
......
...@@ -462,8 +462,9 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -462,8 +462,9 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
uint8_t decoded_output[4]; uint8_t decoded_output[4];
for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) { for (int symbol = 0; symbol < SL_NR_NUMSYM_SLSS_NORMAL_CP - 1;) {
nr_pbch_channel_estimation(UE, nr_pbch_channel_estimation(frame_parms,
frame_parms, &UE->SL_UE_PHY_PARAMS,
UE->nr_gold_pbch,
rxdataF_sz, rxdataF_sz,
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
...@@ -472,6 +473,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -472,6 +473,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
symbol, symbol,
0, 0,
0, 0,
frame_parms->ssb_start_subcarrier,
rxdataF, rxdataF,
1, 1,
rx_slss_id); rx_slss_id);
......
This diff is collapsed.
...@@ -291,12 +291,18 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin ...@@ -291,12 +291,18 @@ int rx_sss(PHY_VARS_NR_UE *phy_vars_ue,int32_t *tot_metric,uint8_t *flip_max,uin
int nr_rx_pbch(PHY_VARS_NR_UE *ue, int nr_rx_pbch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
const int estimateSz, bool is_synchronized,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz], struct complex16 dl_ch_estimates[][estimateSz],
NR_DL_FRAME_PARMS *frame_parms, const NR_DL_FRAME_PARMS *frame_parms,
uint8_t i_ssb, uint8_t i_ssb,
int ssb_start_subcarrier,
int Nid_cell,
fapiPbch_t *result, fapiPbch_t *result,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int *half_frame_bit,
int *ssb_index,
int *ret_symbol_offset,
const struct complex16 rxdataF[][frame_parms->samples_per_slot_wCP]);
#ifndef modOrder #ifndef modOrder
#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS #define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS
...@@ -319,10 +325,6 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -319,10 +325,6 @@ int dump_ue_stats(PHY_VARS_NR_UE *phy_vars_ue,
@param n_frames @param n_frames
@param sa current running mode @param sa current running mode
*/ */
typedef struct {
bool cell_detected;
int rx_offset;
} nr_initial_sync_t;
nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa); nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, int sa);
/*! /*!
...@@ -435,13 +437,13 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, ...@@ -435,13 +437,13 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
// Reuse already existing PBCH functions // Reuse already existing PBCH functions
int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms, const NR_DL_FRAME_PARMS *frame_parms,
int nb_re); int nb_re);
void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL], struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
int nb_re, int nb_re,
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL], struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms, const NR_DL_FRAME_PARMS *frame_parms,
uint8_t output_shift); uint8_t output_shift);
void nr_pbch_unscrambling(int16_t *demod_pbch_e, void nr_pbch_unscrambling(int16_t *demod_pbch_e,
uint16_t Nid, uint16_t Nid,
......
This diff is collapsed.
...@@ -187,13 +187,14 @@ void insert_sss_nr(int16_t *sss_time, ...@@ -187,13 +187,14 @@ void insert_sss_nr(int16_t *sss_time,
* *
*********************************************************************/ *********************************************************************/
static int pss_ch_est_nr(PHY_VARS_NR_UE *ue, static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms,
int nid2,
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]) c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
{ {
int16_t *pss = get_primary_synchro_nr2(ue->common_vars.nid2); int16_t *pss = get_primary_synchro_nr2(nid2);
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
c16_t *sss_ext2 = sss_ext[aarx]; c16_t *sss_ext2 = sss_ext[aarx];
c16_t *pss_ext2 = pss_ext[aarx]; c16_t *pss_ext2 = pss_ext[aarx];
for (int i = 0; i < LENGTH_PSS_NR; i++) { for (int i = 0; i < LENGTH_PSS_NR; i++) {
...@@ -250,16 +251,15 @@ static int pss_ch_est_nr(PHY_VARS_NR_UE *ue, ...@@ -250,16 +251,15 @@ static int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
*********************************************************************/ *********************************************************************/
static int do_pss_sss_extract_nr( static int do_pss_sss_extract_nr(
PHY_VARS_NR_UE *ue, const NR_DL_FRAME_PARMS *frame_parms,
const UE_nr_rxtx_proc_t *proc,
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t doPss, uint8_t doPss,
uint8_t doSss, uint8_t doSss,
uint8_t subframe, uint8_t subframe,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both int ssb_start_subcarrier,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
{ {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n"); AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n");
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
...@@ -275,11 +275,8 @@ static int do_pss_sss_extract_nr( ...@@ -275,11 +275,8 @@ static int do_pss_sss_extract_nr(
c16_t *pss_rxF_ext = pss_ext[aarx]; c16_t *pss_rxF_ext = pss_ext[aarx];
c16_t *sss_rxF_ext = sss_ext[aarx]; c16_t *sss_rxF_ext = sss_ext[aarx];
unsigned int k = frame_parms->first_carrier_offset + unsigned int k = frame_parms->first_carrier_offset + ssb_start_subcarrier
frame_parms->ssb_start_subcarrier + + ((get_softmodem_params()->sl_mode == 0) ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL);
((get_softmodem_params()->sl_mode == 0) ?
PSS_SSS_SUB_CARRIER_START :
PSS_SSS_SUB_CARRIER_START_SL);
if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size; if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
...@@ -333,14 +330,21 @@ static int do_pss_sss_extract_nr( ...@@ -333,14 +330,21 @@ static int do_pss_sss_extract_nr(
* *
*********************************************************************/ *********************************************************************/
static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms,
const UE_nr_rxtx_proc_t *proc,
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
uint8_t subframe, uint8_t subframe,
c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP]) int ssb_start_subcarrier,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
{ {
return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe, rxdataF); return do_pss_sss_extract_nr(frame_parms,
pss_ext,
sss_ext,
1 /* doPss */,
1 /* doSss */,
subframe,
ssb_start_subcarrier,
rxdataF);
} }
/******************************************************************* /*******************************************************************
...@@ -355,31 +359,29 @@ static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, ...@@ -355,31 +359,29 @@ static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
* so Nid_cell in ue context is set according to Nid1 & Nid2 * so Nid_cell in ue context is set according to Nid1 & Nid2
* *
*********************************************************************/ *********************************************************************/
bool rx_sss_nr(PHY_VARS_NR_UE *ue, bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
const UE_nr_rxtx_proc_t *proc, int nid2,
int target_Nid_cell,
int freq_offset_pss,
int ssb_start_subcarrier,
int *Nid_cell,
int32_t *tot_metric, int32_t *tot_metric,
uint8_t *phase_max, uint8_t *phase_max,
int *freq_offset_sss, int *freq_offset_sss,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) c16_t rxdataF[][frame_parms->samples_per_slot_wCP])
{ {
uint8_t i; uint8_t i;
c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0}; c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0};
c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0}; c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0};
uint8_t Nid2 = GET_NID2(ue->common_vars.nid2); uint8_t Nid2 = GET_NID2(nid2);
uint16_t Nid1; uint16_t Nid1;
uint8_t phase; uint8_t phase;
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int32_t metric, metric_re; int32_t metric, metric_re;
int16_t *d; int16_t *d;
// pss sss extraction // pss sss extraction
pss_sss_extract_nr(ue, pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, 0, ssb_start_subcarrier, rxdataF); /* subframe */
proc,
pss_ext,
sss_ext,
0,
rxdataF); /* subframe */
#ifdef DEBUG_PLOT_SSS #ifdef DEBUG_PLOT_SSS
...@@ -406,9 +408,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -406,9 +408,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
// get conjugated channel estimate from PSS, H* = R* \cdot PSS // get conjugated channel estimate from PSS, H* = R* \cdot PSS
// and do channel estimation and compensation based on PSS // and do channel estimation and compensation based on PSS
pss_ch_est_nr(ue, pss_ch_est_nr(frame_parms, nid2, pss_ext, sss_ext);
pss_ext,
sss_ext);
// now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h // now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h
*tot_metric = INT_MIN; *tot_metric = INT_MIN;
...@@ -453,8 +453,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -453,8 +453,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
uint16_t Nid1_start = 0; uint16_t Nid1_start = 0;
uint16_t Nid1_end = N_ID_1_NUMBER; uint16_t Nid1_end = N_ID_1_NUMBER;
if (ue->target_Nid_cell != -1) { if (target_Nid_cell != -1) {
Nid1_start = GET_NID1(ue->target_Nid_cell); Nid1_start = GET_NID1(target_Nid_cell);
Nid1_end = Nid1_start + 1; Nid1_end = Nid1_start + 1;
} }
...@@ -476,7 +476,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -476,7 +476,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
// if the current metric is better than the last save it // if the current metric is better than the last save it
if (metric > *tot_metric) { if (metric > *tot_metric) {
*tot_metric = metric; *tot_metric = metric;
ue->frame_parms.Nid_cell = Nid2+(3*Nid1); *Nid_cell = Nid2 + (3 * Nid1);
*phase_max = phase; *phase_max = phase;
#ifdef DEBUG_SSS_NR #ifdef DEBUG_SSS_NR
...@@ -491,8 +491,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -491,8 +491,8 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
//#ifdef DEBUG_SSS_NR //#ifdef DEBUG_SSS_NR
#define SSS_METRIC_FLOOR_NR (30000) #define SSS_METRIC_FLOOR_NR (30000)
if (*tot_metric > SSS_METRIC_FLOOR_NR) { if (*tot_metric > SSS_METRIC_FLOOR_NR) {
Nid2 = GET_NID2(frame_parms->Nid_cell); Nid2 = GET_NID2(*Nid_cell);
Nid1 = GET_NID1(frame_parms->Nid_cell); Nid1 = GET_NID1(*Nid_cell);
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max); LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
} }
// #endif // #endif
...@@ -504,7 +504,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -504,7 +504,7 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
"Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n", "Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n",
*tot_metric, *tot_metric,
SSS_METRIC_FLOOR_NR, SSS_METRIC_FLOOR_NR,
frame_parms->Nid_cell); *Nid_cell);
return false; return false;
} }
d = (int16_t *)&d_sss[Nid2][Nid1]; d = (int16_t *)&d_sss[Nid2][Nid1];
...@@ -515,10 +515,10 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue, ...@@ -515,10 +515,10 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
double ffo_sss = atan2(im,re)/M_PI/4.3; double ffo_sss = atan2(im,re)/M_PI/4.3;
*freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing); *freq_offset_sss = (int)(ffo_sss*frame_parms->subcarrier_spacing);
double ffo_pss = ((double)ue->common_vars.freq_offset)/frame_parms->subcarrier_spacing; double ffo_pss = ((double)freq_offset_pss) / frame_parms->subcarrier_spacing;
LOG_W(NR_PHY, LOG_W(NR_PHY,
"SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n", "SSS detected, PCI: %d, ffo_pss %f (%i Hz), ffo_sss %f (%i Hz), ffo_pss+ffo_sss %f (%i Hz), nid1: %d, nid2: %d\n",
frame_parms->Nid_cell, *Nid_cell,
ffo_pss, ffo_pss,
(int)(ffo_pss * frame_parms->subcarrier_spacing), (int)(ffo_pss * frame_parms->subcarrier_spacing),
ffo_sss, ffo_sss,
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "common_lib.h" #include "common_lib.h"
#include "fapi_nr_ue_interface.h" #include "fapi_nr_ue_interface.h"
#include "assertions.h" #include "assertions.h"
//#include "openair1/SCHED_NR_UE/defs.h"
#ifdef MEX #ifdef MEX
#define msg mexPrintf #define msg mexPrintf
...@@ -60,9 +61,9 @@ ...@@ -60,9 +61,9 @@
#endif #endif
#define msg(aRGS...) LOG_D(PHY, ##aRGS) #define msg(aRGS...) LOG_D(PHY, ##aRGS)
#endif #endif
//use msg in the real-time thread context // use msg in the real-time thread context
#define msg_nrt printf #define msg_nrt printf
//use msg_nrt in the non real-time context (for initialization, ...) // use msg_nrt in the non real-time context (for initialization, ...)
#ifndef malloc16 #ifndef malloc16
#define malloc16(x) memalign(32,x) #define malloc16(x) memalign(32,x)
#endif #endif
...@@ -123,6 +124,11 @@ typedef enum { ...@@ -123,6 +124,11 @@ typedef enum {
#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg
typedef struct {
uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
uint8_t xtra_byte;
} fapiPbch_t;
typedef struct { typedef struct {
// RRC measurements // RRC measurements
...@@ -614,6 +620,30 @@ typedef struct { ...@@ -614,6 +620,30 @@ typedef struct {
int frame_rx; int frame_rx;
} UE_nr_rxtx_proc_t; } UE_nr_rxtx_proc_t;
typedef struct {
bool cell_detected;
int rx_offset;
int frame_id;
} nr_initial_sync_t;
typedef struct {
nr_gscn_info_t gscnInfo;
int foFlag;
int targetNidCell;
c16_t **rxdata;
NR_DL_FRAME_PARMS *fp;
UE_nr_rxtx_proc_t *proc;
int nFrames;
int halfFrameBit;
int symbolOffset;
int ssbIndex;
int ssbOffset;
int nidCell;
int freqOffset;
nr_initial_sync_t syncRes;
fapiPbch_t pbchResult;
} nr_ue_ssb_scan_t;
typedef struct nr_phy_data_tx_s { typedef struct nr_phy_data_tx_s {
NR_UE_ULSCH_t ulsch; NR_UE_ULSCH_t ulsch;
NR_UE_PUCCH pucch_vars; NR_UE_PUCCH pucch_vars;
......
...@@ -81,12 +81,6 @@ ...@@ -81,12 +81,6 @@
#define DAQ_AGC_ON 1 #define DAQ_AGC_ON 1
#define DAQ_AGC_OFF 0 #define DAQ_AGC_OFF 0
typedef struct {
uint8_t decoded_output[3]; // PBCH paylod not larger than 3B
uint8_t xtra_byte;
} fapiPbch_t;
/** @addtogroup _PHY_PROCEDURES_ /** @addtogroup _PHY_PROCEDURES_
* @{ * @{
*/ */
......
...@@ -387,13 +387,20 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, ...@@ -387,13 +387,20 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id); LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
fapiPbch_t result; fapiPbch_t result;
int hf_frame_bit, ssb_index, symb_offset;
ret = nr_rx_pbch(ue, ret = nr_rx_pbch(ue,
proc, proc,
ue->is_synchronized,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
&ue->frame_parms, &ue->frame_parms,
(ue->frame_parms.ssb_index)&7, (ue->frame_parms.ssb_index) & 7,
ue->frame_parms.ssb_start_subcarrier,
ue->frame_parms.Nid_cell,
&result, &result,
&hf_frame_bit,
&ssb_index,
&symb_offset,
rxdataF); rxdataF);
if (ret==0) { if (ret==0) {
...@@ -884,8 +891,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -884,8 +891,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
nr_slot_fep(ue, fp, proc, (ssb_start_symbol + i) % (fp->symbols_per_slot), rxdataF, link_type_dl); nr_slot_fep(ue, fp, proc, (ssb_start_symbol + i) % (fp->symbols_per_slot), rxdataF, link_type_dl);
start_meas(&ue->dlsch_channel_estimation_stats); start_meas(&ue->dlsch_channel_estimation_stats);
nr_pbch_channel_estimation(ue, nr_pbch_channel_estimation(&ue->frame_parms,
&ue->frame_parms, NULL,
ue->nr_gold_pbch,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
...@@ -894,10 +902,20 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ ...@@ -894,10 +902,20 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
i - 1, i - 1,
ssb_index & 7, ssb_index & 7,
ssb_slot_2 == nr_slot_rx, ssb_slot_2 == nr_slot_rx,
fp->ssb_start_subcarrier,
rxdataF, rxdataF,
false, false,
fp->Nid_cell); fp->Nid_cell);
stop_meas(&ue->dlsch_channel_estimation_stats); stop_meas(&ue->dlsch_channel_estimation_stats);
if (i - 1 == 2)
UEscopeCopy(ue,
pbchDlChEstimateTime,
(void *)dl_ch_estimates_time,
sizeof(c16_t),
fp->nb_antennas_rx,
fp->ofdm_symbol_size,
0);
} }
nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF); nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF);
......
...@@ -193,8 +193,9 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d ...@@ -193,8 +193,9 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_ul); nr_slot_fep(ue, fp, proc, sym, rxdataF, link_type_ul);
start_meas(&sl_phy_params->channel_estimation_stats); start_meas(&sl_phy_params->channel_estimation_stats);
nr_pbch_channel_estimation(ue, nr_pbch_channel_estimation(fp,
fp, &ue->SL_UE_PHY_PARAMS,
ue->nr_gold_pbch,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
...@@ -203,10 +204,19 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d ...@@ -203,10 +204,19 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_d
sym, sym,
0, 0,
0, 0,
fp->ssb_start_subcarrier,
rxdataF, rxdataF,
true, true,
sl_phy_params->sl_config.sl_sync_source.rx_slss_id); sl_phy_params->sl_config.sl_sync_source.rx_slss_id);
stop_meas(&sl_phy_params->channel_estimation_stats); stop_meas(&sl_phy_params->channel_estimation_stats);
if (sym == 12)
UEscopeCopy(ue,
pbchDlChEstimateTime,
(void *)dl_ch_estimates_time,
sizeof(c16_t),
fp->nb_antennas_rx,
fp->ofdm_symbol_size,
0);
// PSBCH present in symbols 0, 5-12 for normal cp // PSBCH present in symbols 0, 5-12 for normal cp
sym = (sym == 0) ? 5 : sym + 1; sym = (sym == 0) ? 5 : sym + 1;
......
...@@ -823,7 +823,7 @@ int main(int argc, char **argv) ...@@ -823,7 +823,7 @@ int main(int argc, char **argv)
init_nr_ue_transport(UE); init_nr_ue_transport(UE);
nr_gold_pbch(UE); nr_gold_pbch(UE->nr_gold_pbch, frame_parms->Nid_cell, frame_parms->Lmax);
// compute the scramblingID_pdcch and the gold pdcch // compute the scramblingID_pdcch and the gold pdcch
UE->scramblingID_pdcch = frame_parms->Nid_cell; UE->scramblingID_pdcch = frame_parms->Nid_cell;
......
...@@ -199,6 +199,7 @@ int main(int argc, char **argv) ...@@ -199,6 +199,7 @@ int main(int argc, char **argv)
uint16_t Nid_cell=0; uint16_t Nid_cell=0;
uint64_t SSB_positions=0x01; uint64_t SSB_positions=0x01;
int ssb_subcarrier_offset = 0; int ssb_subcarrier_offset = 0;
int ssb_scan_threads = 0;
channel_desc_t *gNB2UE; channel_desc_t *gNB2UE;
get_softmodem_params()->sa = 1; get_softmodem_params()->sa = 1;
...@@ -493,8 +494,9 @@ int main(int argc, char **argv) ...@@ -493,8 +494,9 @@ int main(int argc, char **argv)
set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4);
phy_init_nr_gNB(gNB); phy_init_nr_gNB(gNB);
frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset; frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset;
initFloatingCoresTpool(ssb_scan_threads, &nrUE_params.Tpool, false, "UE-tpool");
uint8_t n_hf = 0; int n_hf = 0;
int cyclic_prefix_type = NFAPI_CP_NORMAL; int cyclic_prefix_type = NFAPI_CP_NORMAL;
double fs=0, eps; double fs=0, eps;
...@@ -608,7 +610,7 @@ int main(int argc, char **argv) ...@@ -608,7 +610,7 @@ int main(int argc, char **argv)
exit(-1); exit(-1);
} }
nr_gold_pbch(UE); nr_gold_pbch(UE->nr_gold_pbch, Nid_cell, frame_parms->Lmax);
processingData_L1tx_t msgDataTx; processingData_L1tx_t msgDataTx;
// generate signal // generate signal
...@@ -759,13 +761,16 @@ int main(int argc, char **argv) ...@@ -759,13 +761,16 @@ int main(int argc, char **argv)
} }
if (n_trials==1) { if (n_trials==1) {
LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0],frame_parms->samples_per_frame,1,1); LOG_M("rxsig0.m", "rxs0", UE->common_vars.rxdata[0], frame_parms->samples_per_frame, 1, 1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx > 1)
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],frame_parms->samples_per_frame,1,1); LOG_M("rxsig1.m", "rxs1", UE->common_vars.rxdata[1], frame_parms->samples_per_frame, 1, 1);
} }
if (UE->is_synchronized == 0) { if (UE->is_synchronized == 0) {
UE_nr_rxtx_proc_t proc={0}; UE_nr_rxtx_proc_t proc = {0};
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0); nr_gscn_info_t gscnInfo[MAX_GSCN_BAND] = {0};
const int numGscn = 1;
gscnInfo[0].ssbFirstSC = frame_parms->ssb_start_subcarrier;
nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0, gscnInfo, numGscn);
printf("nr_initial_sync1 returns %s\n", ret.cell_detected ? "cell detected" : "cell not detected"); printf("nr_initial_sync1 returns %s\n", ret.cell_detected ? "cell detected" : "cell not detected");
if (!ret.cell_detected) if (!ret.cell_detected)
n_errors++; n_errors++;
...@@ -788,8 +793,9 @@ int main(int argc, char **argv) ...@@ -788,8 +793,9 @@ int main(int argc, char **argv)
for (int i = UE->symbol_offset + 1; i < UE->symbol_offset + 4; i++) { for (int i = UE->symbol_offset + 1; i < UE->symbol_offset + 4; i++) {
nr_slot_fep(UE, frame_parms, &proc, i % frame_parms->symbols_per_slot, rxdataF, link_type_dl); nr_slot_fep(UE, frame_parms, &proc, i % frame_parms->symbols_per_slot, rxdataF, link_type_dl);
nr_pbch_channel_estimation(UE, nr_pbch_channel_estimation(&UE->frame_parms,
&UE->frame_parms, &UE->SL_UE_PHY_PARAMS,
UE->nr_gold_pbch,
estimateSz, estimateSz,
dl_ch_estimates, dl_ch_estimates,
dl_ch_estimates_time, dl_ch_estimates_time,
...@@ -798,12 +804,15 @@ int main(int argc, char **argv) ...@@ -798,12 +804,15 @@ int main(int argc, char **argv)
i - (UE->symbol_offset + 1), i - (UE->symbol_offset + 1),
ssb_index % 8, ssb_index % 8,
n_hf, n_hf,
frame_parms->ssb_start_subcarrier,
rxdataF, rxdataF,
false, false,
frame_parms->Nid_cell); frame_parms->Nid_cell);
} }
fapiPbch_t result; fapiPbch_t result;
ret = nr_rx_pbch(UE, &proc, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, &result, rxdataF); int ret_ssb_idx;
int ret_symbol_offset;
ret = nr_rx_pbch(UE, &proc, true, estimateSz, dl_ch_estimates, frame_parms, ssb_index % 8, frame_parms->ssb_start_subcarrier, Nid_cell, &result, &n_hf, &ret_ssb_idx, &ret_symbol_offset, rxdataF);
if (ret == 0) { if (ret == 0) {
// UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically // UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically
......
...@@ -97,71 +97,6 @@ ...@@ -97,71 +97,6 @@
extern uint16_t sf_ahead; extern uint16_t sf_ahead;
// synchronization raster per band tables (Rel.15)
// (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1)
// band nb, sub-carrier spacing index, Range of gscn (First, Step size, Last)
const sync_raster_t sync_raster[] = {
{1, 0, 5279, 1, 5419},
{2, 0, 4829, 1, 4969},
{3, 0, 4517, 1, 4693},
{5, 0, 2177, 1, 2230},
{5, 1, 2183, 1, 2224},
{7, 0, 6554, 1, 6718},
{8, 0, 2318, 1, 2395},
{12, 0, 1828, 1, 1858},
{13, 0, 1871, 1, 1885},
{14, 0, 1901, 1, 1915},
{18, 0, 2156, 1, 2182},
{20, 0, 1982, 1, 2047},
{24, 0, 3818, 1, 3892},
{24, 1, 3824, 1, 3886},
{25, 0, 4829, 1, 4981},
{26, 0, 2153, 1, 2230},
{28, 0, 1901, 1, 2002},
{29, 0, 1798, 1, 1813},
{30, 0, 5879, 1, 5893},
{34, 0, 5030, 1, 5056},
{34, 1, 5036, 1, 5050},
{38, 0, 6431, 1, 6544},
{38, 1, 6437, 1, 6538},
{39, 0, 4706, 1, 4795},
{39, 1, 4712, 1, 4789},
{40, 1, 5762, 1, 5989},
{41, 0, 6246, 3, 6717},
{41, 1, 6252, 3, 6714},
{48, 1, 7884, 1, 7982},
{50, 0, 3584, 1, 3787},
{51, 0, 3572, 1, 3574},
{53, 0, 6215, 1, 6232},
{53, 1, 6221, 1, 6226},
{65, 0, 5279, 1, 5494},
{66, 0, 5279, 1, 5494},
{66, 1, 5285, 1, 5488},
{67, 0, 1850, 1, 1888},
{70, 0, 4993, 1, 5044},
{71, 0, 1547, 1, 1624},
{74, 0, 3692, 1, 3790},
{75, 0, 3584, 1, 3787},
{76, 0, 3572, 1, 3574},
{77, 1, 7711, 1, 8329},
{78, 1, 7711, 1, 8051},
{79, 1, 8480, 16, 8880},
{85, 0, 1826, 1, 1858},
{90, 1, 6252, 1, 6714},
{91, 0, 3572, 1, 3574},
{92, 0, 3584, 1, 3787},
{93, 0, 3572, 1, 3574},
{94, 0, 3584, 1, 3587},
{257, 3, 22388, 1, 22558},
{257, 4, 22390, 2, 22556},
{258, 3, 22257, 1, 22443},
{258, 4, 22258, 2, 22442},
{260, 3, 22995, 1, 23166},
{260, 4, 22996, 2, 23164},
{261, 3, 22446, 1, 22492},
{261, 4, 22446, 2, 22490},
};
extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency, extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency,
int32_t uplink_frequency_offset, uint32_t frame_type); int32_t uplink_frequency_offset, uint32_t frame_type);
...@@ -960,8 +895,6 @@ void RCconfig_NR_L1(void) ...@@ -960,8 +895,6 @@ void RCconfig_NR_L1(void)
} }
} }
static void check_ssb_raster(uint64_t freq, int band, int scs);
static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME) static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME)
{ {
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc)); NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc));
...@@ -1536,56 +1469,6 @@ void config_security(gNB_RRC_INST *rrc) ...@@ -1536,56 +1469,6 @@ void config_security(gNB_RRC_INST *rrc)
} }
} }
// Section 5.4.3 of 38.101-1 and -2
static void check_ssb_raster(uint64_t freq, int band, int scs)
{
int start_gscn = 0, step_gscn = 0, end_gscn = 0;
for (int i = 0; i < sizeof(sync_raster) / sizeof(sync_raster_t); i++) {
if (sync_raster[i].band == band &&
sync_raster[i].scs_index == scs) {
start_gscn = sync_raster[i].first_gscn;
step_gscn = sync_raster[i].step_gscn;
end_gscn = sync_raster[i].last_gscn;
break;
}
}
AssertFatal(start_gscn != 0, "Couldn't find band %d with SCS %d\n", band, scs);
int gscn;
if (freq < 3000000000) {
int N = 0;
int M = 0;
for (int k = 0; k < 3; k++) {
M = (k << 1) + 1;
if ((freq - M * 50000) % 1200000 == 0) {
N = (freq - M * 50000) / 1200000;
break;
}
}
AssertFatal(N != 0, "SSB frequency %lu Hz not on the synchronization raster (N * 1200kHz + M * 50 kHz)\n",
freq);
gscn = (3 * N) + (M - 3) / 2;
}
else if (freq < 24250000000) {
AssertFatal((freq - 3000000000) % 1440000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (3000 MHz + N * 1.44 MHz)\n",
freq);
gscn = ((freq - 3000000000) / 1440000) + 7499;
}
else {
AssertFatal((freq - 24250080000) % 17280000 == 0,
"SSB frequency %lu Hz not on the synchronization raster (24250.08 MHz + N * 17.28 MHz)\n",
freq);
gscn = ((freq - 24250080000) / 17280000) + 22256;
}
AssertFatal(gscn >= start_gscn && gscn <= end_gscn,
"GSCN %d corresponding to SSB frequency %lu does not belong to GSCN range for band %d\n",
gscn, freq, band);
int rel_gscn = gscn - start_gscn;
AssertFatal(rel_gscn % step_gscn == 0,
"GSCN %d corresponding to SSB frequency %lu not in accordance with GSCN step for band %d\n",
gscn, freq, band);
}
void RCconfig_NRRRC(gNB_RRC_INST *rrc) void RCconfig_NRRRC(gNB_RRC_INST *rrc)
{ {
......
...@@ -1038,6 +1038,7 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, ...@@ -1038,6 +1038,7 @@ static int handle_bcch_bch(NR_UE_MAC_INST_t *mac,
mac->mib_ssb = ssb_index; mac->mib_ssb = ssb_index;
mac->physCellId = cell_id; mac->physCellId = cell_id;
mac->mib_additional_bits = additional_bits; mac->mib_additional_bits = additional_bits;
mac->ssb_start_subcarrier = ssb_start_subcarrier;
if(ssb_length == 64) if(ssb_length == 64)
mac->frequency_range = FR2; mac->frequency_range = FR2;
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment