Commit fed90543 authored by Laurent OpenCells's avatar Laurent OpenCells

Merge branch 'develop' of gitlab.eurecom.fr:oai/openairinterface5g into sanitize-v1

parents 0317d672 7ed03d50
...@@ -23,6 +23,7 @@ gNBs = ...@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0; ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1; pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200;
......
...@@ -23,6 +23,7 @@ gNBs = ...@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0; ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1; pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
servingCellConfigCommon = ( servingCellConfigCommon = (
{ {
......
...@@ -22,6 +22,7 @@ gNBs = ...@@ -22,6 +22,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0; ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1; pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200;
...@@ -250,7 +251,7 @@ L1s = ( ...@@ -250,7 +251,7 @@ L1s = (
{ {
num_cc = 1; num_cc = 1;
tr_n_preference = "local_mac"; tr_n_preference = "local_mac";
pusch_proc_threads = 8; pusch_proc_threads = 6;
} }
); );
......
...@@ -1330,7 +1330,8 @@ ...@@ -1330,7 +1330,8 @@
(Test3: 30kHz SCS, 273 PRBs, Prach format A2), (Test3: 30kHz SCS, 273 PRBs, Prach format A2),
(Test4: 30kHz SCS, 106 PRBs, Prach format 0), (Test4: 30kHz SCS, 106 PRBs, Prach format 0),
(Test5: 120kHz SCS, 32 PRBs, Prach format A2), (Test5: 120kHz SCS, 32 PRBs, Prach format A2),
(Test6: 120kHz SCS, 66 PRBs, Prach format A2)</desc> (Test6: 120kHz SCS, 66 PRBs, Prach format A2),
(Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)</desc>
<pre_compile_prog></pre_compile_prog> <pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args> <compile_prog_args> --phy_simulators -c </compile_prog_args>
...@@ -1342,8 +1343,9 @@ ...@@ -1342,8 +1343,9 @@
-a -s -30 -n 100 -p 63 -R 273 -a -s -30 -n 100 -p 63 -R 273
-a -s -30 -n 100 -p 63 -R 106 -c 4 -a -s -30 -n 100 -p 63 -R 106 -c 4
-a -s -30 -n 100 -p 32 -R 32 -m 3 -c52 -a -s -30 -n 100 -p 32 -R 32 -m 3 -c52
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52</main_exec_args> -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6</tags> -a -s -30 -n 100 -R 66 -m 3 -c52 -H</main_exec_args>
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7</tags>
<search_expr_true>PRACH test OK</search_expr_true> <search_expr_true>PRACH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns> <nruns>3</nruns>
......
...@@ -44,10 +44,11 @@ Our code might not work with all 5G phones yet, but we are constantly improving ...@@ -44,10 +44,11 @@ Our code might not work with all 5G phones yet, but we are constantly improving
* Oppo Reno 5G * Oppo Reno 5G
* Samsung A90 5G * Samsung A90 5G
* Google Pixel 5G * Google Pixel 5G (note1)
* Simcom SIMCOM8200EA * Simcom SIMCOM8200EA
* Quectel RM500Q-GL * Quectel RM500Q-GL
Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see https://developers.google.com/android/images)
## Repository ## Repository
......
...@@ -468,15 +468,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) { ...@@ -468,15 +468,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
PHY_VARS_gNB *gNB; PHY_VARS_gNB *gNB;
if (RC.gNB == NULL) { if (RC.gNB == NULL) {
RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *)); RC.gNB = (PHY_VARS_gNB **) calloc(1+RC.nb_nr_L1_inst, sizeof(PHY_VARS_gNB *));
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB); LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
} }
for (inst=0; inst<RC.nb_nr_L1_inst; inst++) { for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
if (RC.gNB[inst] == NULL) { if (RC.gNB[inst] == NULL) {
RC.gNB[inst] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB)); RC.gNB[inst] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
memset((void*)RC.gNB[inst],0,sizeof(PHY_VARS_gNB));
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]); LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
} }
gNB = RC.gNB[inst]; gNB = RC.gNB[inst];
......
...@@ -27,12 +27,9 @@ ...@@ -27,12 +27,9 @@
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16}; uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) 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;
uint8_t half_frame_index = fp->half_frame_bit;
uint8_t i_ssb = fp->ssb_index;
int symbol = 0; int symbol = 0;
uint8_t n, n_temp; uint8_t n, n_temp;
nr_ssb_type_e type = fp->ssb_type; nr_ssb_type_e type = fp->ssb_type;
...@@ -69,9 +66,6 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) ...@@ -69,9 +66,6 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
} }
if (half_frame_index)
symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
return symbol; return symbol;
} }
......
...@@ -392,7 +392,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config); ...@@ -392,7 +392,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp); int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int 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);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* \warning * \warning
*/ */
#include <LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
#include "nr_dci.h" #include "nr_dci.h"
#include "nr_dlsch.h" #include "nr_dlsch.h"
#include "nr_sch_dmrs.h" #include "nr_sch_dmrs.h"
...@@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, ...@@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// compute rb_offset and n_prb based on frequency allocation // compute rb_offset and n_prb based on frequency allocation
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15); nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB; cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB;
}
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) { for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
/*The coreset is initialised /*The coreset is initialised
......
...@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
///Payload generation ///Payload generation
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH)); memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
pbch->pbch_a=0; pbch->pbch_a=0;
uint8_t ssb_index = frame_parms->ssb_index; uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex;
uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload; uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
uint8_t Lmax = frame_parms->Lmax; uint8_t Lmax = frame_parms->Lmax;
for (int i=0; i<NR_PBCH_PDU_BITS; i++) for (int i=0; i<NR_PBCH_PDU_BITS; i++)
......
...@@ -780,7 +780,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -780,7 +780,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
} }
} else { // This is the high-speed case } else { // This is the high-speed case
new_dft = 0; new_dft = 0;
nr_fill_du(N_ZC,prach_root_sequence_map);
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift // preamble index and find the corresponding cyclic shift
// Check if all shifts for that root have been processed // Check if all shifts for that root have been processed
...@@ -788,7 +788,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -788,7 +788,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
not_found = 1; not_found = 1;
new_dft = 1; new_dft = 1;
preamble_index0 -= numshift; preamble_index0 -= numshift;
(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++); //(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
while (not_found == 1) { while (not_found == 1) {
// current root depending on rootSequenceIndex // current root depending on rootSequenceIndex
......
...@@ -73,6 +73,8 @@ void compute_nr_prach_seq(uint8_t short_sequence, ...@@ -73,6 +73,8 @@ void compute_nr_prach_seq(uint8_t short_sequence,
uint8_t rootSequenceIndex, uint8_t rootSequenceIndex,
uint32_t X_u[64][839]); uint32_t X_u[64][839]);
void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map);
void init_nr_prach_tables(int N_ZC); void init_nr_prach_tables(int N_ZC);
/**@}*/ /**@}*/
......
...@@ -589,7 +589,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, ...@@ -589,7 +589,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i)); frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
} }
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms); ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb);
if (frame_parms->half_frame_bit)
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
uint8_t frame_number_4lsb = 0; uint8_t frame_number_4lsb = 0;
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
......
...@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ ...@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
#endif #endif
not_found = 1; not_found = 1;
nr_fill_du(N_ZC,prach_root_sequence_map);
preamble_index0 = preamble_index; preamble_index0 = preamble_index;
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift // preamble index and find the corresponding cyclic shift
......
...@@ -182,7 +182,10 @@ typedef struct { ...@@ -182,7 +182,10 @@ typedef struct {
int16_t sqrt_rho_b; int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t; } NR_gNB_DLSCH_t;
typedef struct {
bool active;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
} NR_gNB_SSB_t;
typedef struct { typedef struct {
int frame; int frame;
...@@ -711,10 +714,10 @@ typedef struct PHY_VARS_gNB_s { ...@@ -711,10 +714,10 @@ typedef struct PHY_VARS_gNB_s {
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu; // nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu; // nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
uint16_t num_pdsch_rnti[80]; uint16_t num_pdsch_rnti[80];
NR_gNB_PBCH pbch; NR_gNB_SSB_t ssb[64];
NR_gNB_PBCH pbch;
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
NR_gNB_COMMON common_vars; NR_gNB_COMMON common_vars;
NR_gNB_PRACH prach_vars; NR_gNB_PRACH prach_vars;
......
...@@ -50,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, ...@@ -50,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n", AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag); dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
if (gNB->ssb[i_ssb].active)
AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
else {
gNB->ssb[i_ssb].active = true;
memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
}
} }
/*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc, /*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc,
...@@ -166,14 +173,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ ...@@ -166,14 +173,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB->dlsch[i][0]->harq_mask=0; gNB->dlsch[i][0]->harq_mask=0;
} }
gNB->pbch_configured=0;
for (int i=0;i<number_dl_pdu;i++) { for (int i=0;i<number_dl_pdu;i++) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i]; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType); LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) { switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
gNB->pbch_configured=1;
if(NFAPI_MODE != NFAPI_MODE_VNF) if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot, handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
...@@ -257,4 +261,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ ...@@ -257,4 +261,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
} }
} }
\ No newline at end of file
...@@ -67,85 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME ...@@ -67,85 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco);
} }
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF; int **txdataF = gNB->common_vars.txdataF;
uint8_t ssb_index, ssb_per_slot=0, n_hf; uint8_t ssb_index, n_hf;
uint16_t ssb_start_symbol, rel_slot; uint16_t ssb_start_symbol;
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
uint16_t slots_per_hf = (fp->slots_per_frame)>>1; uint16_t slots_per_hf = (fp->slots_per_frame)>>1;
n_hf = fp->half_frame_bit; if (slot<slots_per_hf)
n_hf=0;
else
n_hf=1;
// if SSB periodicity is 5ms, they are transmitted in both half frames ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
if ( cfg->ssb_table.ssb_period.value == 0) { LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n",frame,slot,ssb_index);
if (slot<slots_per_hf)
n_hf=0;
else
n_hf=1;
}
// to set a effective slot number in the half frame where the SSB is supposed to be int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb
rel_slot = (n_hf)? (slot-slots_per_hf) : slot; ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
if(rel_slot<38 && rel_slot>=0) { // there is no SSB beyond slot 37
for (int i=0; i<2; i++) { // max two SSB per slot
ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index
if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
ssb_per_slot++;
fp->ssb_index = ssb_index;
int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb
ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (cfg->carrier_config.num_tx_ant.value <= 4)
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
else
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (T_ACTIVE(T_GNB_PHY_MIB)) {
unsigned char bch[3];
bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
}
nr_generate_pbch(&gNB->pbch, nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
&gNB->ssb_pdu,
gNB->nr_pbch_interleaver, LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
&txdataF[0][txdataF_offset], nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
AMP, nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
ssb_start_symbol,
n_hf, frame, cfg, fp); if (cfg->carrier_config.num_tx_ant.value <= 4)
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
// SSB beamforming is handled at PHY else
// currently our PHY does not support switching more than once a slot. nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
if (ssb_per_slot>1) {
LOG_W(PHY,"beamforming currently not supported for more than one SSB per slot\n"); if (T_ACTIVE(T_GNB_PHY_MIB)) {
} unsigned char bch[3];
else if (ssb_per_slot==1) { bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value); bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
for (int j=0;j<fp->symbols_per_slot;j++) bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value; T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
}
}
}
} }
// Beam_id is currently used only for FR2
if (fp->freq_range==nr_FR2){
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
for (int j=0;j<fp->symbols_per_slot;j++)
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
}
nr_generate_pbch(&gNB->pbch,
&ssb_pdu,
gNB->nr_pbch_interleaver,
&txdataF[0][txdataF_offset],
AMP,
ssb_start_symbol,
n_hf, frame, cfg, fp);
} }
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
int frame,int slot, int frame,int slot,
int do_meas) { int do_meas) {
...@@ -153,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -153,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int offset = gNB->CC_id; int offset = gNB->CC_id;
uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
if (cfg->ssb_table.ssb_period.value > 1)
ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ;
if ((cfg->cell_config.frame_duplex_type.value == TDD) && if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return; (nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
...@@ -174,8 +148,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ...@@ -174,8 +148,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity for (int i=0; i<fp->Lmax; i++) {
nr_common_signal_procedures(gNB,frame, slot); if (gNB->ssb[i].active) {
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
gNB->ssb[i].active = false;
}
}
} }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
...@@ -468,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { ...@@ -468,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
(pucch->frame == frame_rx) && (pucch->frame == frame_rx) &&
(pucch->slot == slot_rx) ) { (pucch->slot == slot_rx) ) {
gNB->ulmask_symb = symbol; gNB->ulmask_symb = symbol;
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu; nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
if ((symbol>=pucch_pdu->start_symbol_index) && if ((symbol>=pucch_pdu->start_symbol_index) &&
(symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){ (symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
for (rb=0; rb<pucch_pdu->prb_size; rb++) { for (rb=0; rb<pucch_pdu->prb_size; rb++) {
......
...@@ -40,7 +40,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_ ...@@ -40,7 +40,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot); void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
......
...@@ -173,6 +173,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id, ...@@ -173,6 +173,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
} }
void config_common(int Mod_idP, void config_common(int Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts, int pdsch_AntennaPorts,
int pusch_AntennaPorts, int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc NR_ServingCellConfigCommon_t *scc
...@@ -679,7 +680,7 @@ int main(int argc, char **argv) ...@@ -679,7 +680,7 @@ int main(int argc, char **argv)
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t)); NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup)); NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
prepare_scc(rrc.carrier.servingcellconfigcommon); prepare_scc(rrc.carrier.servingcellconfigcommon);
uint64_t ssb_bitmap; uint64_t ssb_bitmap = 1;
fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu); fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0 ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
fix_scc(scc,ssb_bitmap); fix_scc(scc,ssb_bitmap);
...@@ -858,7 +859,8 @@ int main(int argc, char **argv) ...@@ -858,7 +859,8 @@ int main(int argc, char **argv)
// generate signal // generate signal
AssertFatal(input_fd==NULL,"Not ready for input signal file\n"); AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
gNB->pbch_configured = 1; gNB->pbch_configured = 1;
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234; gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
//Configure UE //Configure UE
rrc.carrier.MIB = (uint8_t*) malloc(4); rrc.carrier.MIB = (uint8_t*) malloc(4);
...@@ -984,7 +986,7 @@ int main(int argc, char **argv) ...@@ -984,7 +986,7 @@ int main(int argc, char **argv)
printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb ); printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
} }
if (run_initial_sync) if (run_initial_sync)
nr_common_signal_procedures(gNB,frame,slot); nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
else else
phy_procedures_gNB_TX(gNB,frame,slot,0); phy_procedures_gNB_TX(gNB,frame,slot,0);
......
...@@ -119,7 +119,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB, ...@@ -119,7 +119,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char c; char c;
int i,aa;//,l; int i,aa,start_symbol;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0; double cfo=0;
uint8_t snr1set=0; uint8_t snr1set=0;
...@@ -426,29 +426,28 @@ int main(int argc, char **argv) ...@@ -426,29 +426,28 @@ int main(int argc, char **argv)
switch (mu) { switch (mu) {
case 1: case 1:
scs = 30000; scs = 30000;
if (N_RB_DL == 217) { frame_parms->Lmax = 8;
fs = 122.88e6; if (N_RB_DL == 217) {
bw = 80e6; fs = 122.88e6;
bw = 80e6;
} }
else if (N_RB_DL == 245) { else if (N_RB_DL == 245) {
fs = 122.88e6; fs = 122.88e6;
bw = 90e6; bw = 90e6;
} }
else if (N_RB_DL == 273) { else if (N_RB_DL == 273) {
fs = 122.88e6; fs = 122.88e6;
bw = 100e6; bw = 100e6;
} }
else if (N_RB_DL == 106) { else if (N_RB_DL == 106) {
fs = 61.44e6; fs = 61.44e6;
bw = 40e6; bw = 40e6;
} }
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break; break;
case 3: case 3:
frame_parms->Lmax = 64;
scs = 120000; scs = 120000;
if (N_RB_DL == 66) { if (N_RB_DL == 66) {
fs = 122.88e6; fs = 122.88e6;
...@@ -457,6 +456,7 @@ int main(int argc, char **argv) ...@@ -457,6 +456,7 @@ int main(int argc, char **argv)
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
break; break;
} }
// cfo with respect to sub-carrier spacing // cfo with respect to sub-carrier spacing
eps = cfo/scs; eps = cfo/scs;
...@@ -510,7 +510,6 @@ int main(int argc, char **argv) ...@@ -510,7 +510,6 @@ int main(int argc, char **argv)
printf("Allocating %d samples for txdata\n",frame_length_complex_samples); printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int)); txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(r_re[i],frame_length_complex_samples*sizeof(int)); bzero(r_re[i],frame_length_complex_samples*sizeof(int));
} }
if (pbch_file_fd!=NULL) { if (pbch_file_fd!=NULL) {
...@@ -536,60 +535,68 @@ int main(int argc, char **argv) ...@@ -536,60 +535,68 @@ int main(int argc, char **argv)
} }
nr_gold_pbch(UE); nr_gold_pbch(UE);
// generate signal // generate signal
if (input_fd==NULL) { if (input_fd==NULL) {
gNB->pbch_configured = 1;
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
for (int slot=0;slot<frame_parms->slots_per_frame;slot++) { for (i=0; i<frame_parms->Lmax; i++) {
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) if((SSB_positions >> i) & 0x01) {
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
nr_common_signal_procedures (gNB,frame,slot); gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
if (cyclic_prefix_type == 1) { int slot = start_symbol/14;
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
frame_parms->ofdm_symbol_size, memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
12,
frame_parms->nb_prefix_samples, nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
CYCLIC_PREFIX);
} else { for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
/* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], if (cyclic_prefix_type == 1) {
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
14, &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms);*/ frame_parms->ofdm_symbol_size,
PHY_ofdm_mod(gNB->common_vars.txdataF[aa], 12,
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], frame_parms->nb_prefix_samples,
frame_parms->ofdm_symbol_size, CYCLIC_PREFIX);
1, } else {
frame_parms->nb_prefix_samples0, /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
CYCLIC_PREFIX); &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
14,
apply_nr_rotation(frame_parms, frame_parms);*/
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)], PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
slot, (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
0, frame_parms->ofdm_symbol_size,
1, 1,
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0); frame_parms->nb_prefix_samples0,
PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size], CYCLIC_PREFIX);
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size, apply_nr_rotation(frame_parms,
13, (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms->nb_prefix_samples, slot,
CYCLIC_PREFIX); 0,
apply_nr_rotation(frame_parms, 1,
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
slot,
1, PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
13, (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); frame_parms->ofdm_symbol_size,
} 13,
} frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
apply_nr_rotation(frame_parms,
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
slot,
1,
13,
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
}
}
}
} }
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
if (gNB->frame_parms.nb_antennas_tx>1) if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
...@@ -598,9 +605,9 @@ int main(int argc, char **argv) ...@@ -598,9 +605,9 @@ int main(int argc, char **argv)
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0); printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used
if (fread(txdata[0], if (fread(txdata[0],
sizeof(int32_t), sizeof(int32_t),
frame_length_complex_samples, frame_length_complex_samples,
input_fd) != frame_length_complex_samples) { input_fd) != frame_length_complex_samples) {
printf("error reading from file\n"); printf("error reading from file\n");
//exit(-1); //exit(-1);
} }
...@@ -684,10 +691,9 @@ int main(int argc, char **argv) ...@@ -684,10 +691,9 @@ int main(int argc, char **argv)
UE->rx_offset=0; UE->rx_offset=0;
uint8_t ssb_index = 0; uint8_t ssb_index = 0;
while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb
frame_parms->ssb_index = ssb_index; UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame); int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
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, nr_slot_fep(UE,
&proc, &proc,
...@@ -716,7 +722,7 @@ int main(int argc, char **argv) ...@@ -716,7 +722,7 @@ int main(int argc, char **argv)
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte); payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
for (i=0;i<3;i++){ for (i=0;i<3;i++){
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff)); payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
} }
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte); //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
//printf("ret %d\n", payload_ret); //printf("ret %d\n", payload_ret);
......
...@@ -205,7 +205,7 @@ int main(int argc, char **argv){ ...@@ -205,7 +205,7 @@ int main(int argc, char **argv){
randominit(0); randominit(0);
while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { while ((c = getopt (argc, argv, "hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
switch (c) { switch (c) {
case 'a': case 'a':
printf("Running AWGN simulation\n"); printf("Running AWGN simulation\n");
...@@ -218,6 +218,10 @@ int main(int argc, char **argv){ ...@@ -218,6 +218,10 @@ int main(int argc, char **argv){
config_index = atoi(optarg); config_index = atoi(optarg);
break; break;
case 'l':
loglvl = atoi(optarg);
break;
case 'r': case 'r':
msg1_frequencystart = atoi(optarg); msg1_frequencystart = atoi(optarg);
break; break;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#define TABLE_38213_13_1_NUM_INDEXES 15 #define TABLE_38213_13_1_NUM_INDEXES 15
#define TABLE_38213_13_2_NUM_INDEXES 14 #define TABLE_38213_13_2_NUM_INDEXES 14
...@@ -418,14 +419,6 @@ typedef enum { ...@@ -418,14 +419,6 @@ typedef enum {
NR_RNTI_MCS_C, NR_RNTI_MCS_C,
} nr_rnti_type_t; } nr_rnti_type_t;
typedef enum subcarrier_spacing_e {
scs_15kHz = 0x1,
scs_30kHz = 0x2,
scs_60kHz = 0x4,
scs_120kHz = 0x8,
scs_240kHz = 0x16
} subcarrier_spacing_t;
typedef enum channel_bandwidth_e { typedef enum channel_bandwidth_e {
bw_5MHz = 0x1, bw_5MHz = 0x1,
bw_10MHz = 0x2, bw_10MHz = 0x2,
...@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s { ...@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
uint32_t ssb_length; uint32_t ssb_length;
uint32_t ssb_index; uint32_t ssb_index;
uint32_t cset_start_rb; uint32_t cset_start_rb;
bool active;
} NR_Type0_PDCCH_CSS_config_t; } NR_Type0_PDCCH_CSS_config_t;
#endif /*__LAYER2_MAC_H__ */ #endif /*__LAYER2_MAC_H__ */
......
...@@ -36,6 +36,13 @@ ...@@ -36,6 +36,13 @@
#define reserved 0xffff #define reserved 0xffff
// start symbols for SSB types A,B,C,D,E
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
uint16_t symbol_ssb_BD[64]={4,8,16,20,32,36,44,48,60,64,72,76,88,92,100,104,144,148,156,160,172,176,184,188,200,204,212,216,228,232,240,244,284,288,
296,300,312,316,324,328,340,344,352,356,368,372,380,384,424,428,436,440,452,456,464,468,480,484,492,496,508,512,520,524};
uint16_t symbol_ssb_E[64]={8,12,16,20,32,36,40,44,64,68,72,76,88,92,96,100,120,124,128,132,144,148,152,156,176,180,184,188,200,204,208,212,288,292,
296,300,312,316,320,324,344,348,352,356,368,372,376,380,400,404,408,412,424,428,432,436,456,460,464,468,480,484,488,492};
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160}; const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz // Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
...@@ -3008,56 +3015,58 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, ...@@ -3008,56 +3015,58 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
return valid; return valid;
} }
uint32_t get_ssb_slot(uint32_t ssb_index){ uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb) {
// this function now only support f <= 3GHz
return ssb_index & 0x3 ;
// return first_symbol(case, freq, ssb_index) / 14 switch (scs) {
case NR_SubcarrierSpacing_kHz15:
return symbol_ssb_AC[i_ssb]; //type A
case NR_SubcarrierSpacing_kHz30:
if (band == 5 || band == 66)
return symbol_ssb_BD[i_ssb]; //type B
else
return symbol_ssb_AC[i_ssb]; //type C
case NR_SubcarrierSpacing_kHz120:
return symbol_ssb_BD[i_ssb]; //type D
case NR_SubcarrierSpacing_kHz240:
return symbol_ssb_E[i_ssb];
default:
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",scs);
}
} }
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
NR_MIB_t *mib, frame_t frameP,
uint8_t extra_bits, NR_MIB_t *mib,
uint32_t ssb_length, uint8_t num_slot_per_frame,
uint32_t ssb_index, uint8_t ssb_subcarrier_offset,
uint32_t ssb_offset_point_a) { uint16_t ssb_start_symbol,
NR_SubcarrierSpacing_t scs_ssb,
frequency_range_t frequency_range,
uint32_t ssb_index,
uint32_t ssb_offset_point_a) {
// deafult for testing NR_SubcarrierSpacing_t scs_pdcch;
subcarrier_spacing_t scs_ssb = scs_30kHz;
channel_bandwidth_t min_channel_bw = bw_10MHz;
frequency_range_t frequency_range = FR1;
const uint32_t num_slot_per_frame = 20;
type0_PDCCH_CSS_config->ssb_length = ssb_length; channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104
type0_PDCCH_CSS_config->ssb_index = ssb_index;
type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused);
uint16_t frame_number_4lsb = 0; if (frequency_range == FR2) {
for (int i=0; i<4; i++) { if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i); scs_pdcch = NR_SubcarrierSpacing_kHz60;
else
scs_pdcch = NR_SubcarrierSpacing_kHz120;
} }
else {
uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5] frequency_range = FR1;
uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset; if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
scs_pdcch = NR_SubcarrierSpacing_kHz15;
type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4; else
type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb; scs_pdcch = NR_SubcarrierSpacing_kHz30;
if(type0_PDCCH_CSS_config->ssb_length == 64){
type0_PDCCH_CSS_config->ssb_index = type0_PDCCH_CSS_config->ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] }
}else{
if(ssb_subcarrier_offset_msb){
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
}
} }
// assume carrier frequency < 6GHz type0_PDCCH_CSS_config->ssb_index = ssb_index;
subcarrier_spacing_t scs_pdcch; type0_PDCCH_CSS_config->frame = frameP;
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
scs_pdcch = scs_15kHz; uint8_t ssb_slot = ssb_start_symbol/14;
}else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
scs_pdcch = scs_30kHz;
}
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13 uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero); uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero);
...@@ -3068,8 +3077,8 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3068,8 +3077,8 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = -1; type0_PDCCH_CSS_config->rb_offset = -1;
// type0-pdcch coreset // type0-pdcch coreset
switch( (scs_ssb << 5) | scs_pdcch ){ switch( (scs_ssb << 3) | scs_pdcch ){
case (scs_15kHz << 5) | scs_15kHz : case (NR_SubcarrierSpacing_kHz15 << 5) | NR_SubcarrierSpacing_kHz15:
AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n"); AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb]; type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb];
...@@ -3077,7 +3086,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3077,7 +3086,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb]; type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
break; break;
case (scs_15kHz << 5) | scs_30kHz: case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz30:
AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n"); AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb]; type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb];
...@@ -3085,7 +3094,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3085,7 +3094,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb]; type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
break; break;
case (scs_30kHz << 5) | scs_15kHz: case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz15:
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n"); AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
...@@ -3102,7 +3111,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3102,7 +3111,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
break; break;
case (scs_30kHz << 5) | scs_30kHz: case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz30:
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb]; type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb];
...@@ -3118,7 +3127,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3118,7 +3127,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
}else{ ; } }else{ ; }
break; break;
case (scs_120kHz << 5) | scs_60kHz: case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz60:
AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n"); AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
if(index_4msb & 0x7){ if(index_4msb & 0x7){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
...@@ -3135,7 +3144,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3135,7 +3144,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
} }
break; break;
case (scs_120kHz << 5) | scs_120kHz: case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz120:
AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n"); AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
if(index_4msb & 0x3){ if(index_4msb & 0x3){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
...@@ -3152,7 +3161,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3152,7 +3161,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
} }
break; break;
case (scs_240kHz << 5) | scs_60kHz: case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz60:
AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n"); AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb]; type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb];
...@@ -3160,7 +3169,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3160,7 +3169,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb]; type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
break; break;
case (scs_240kHz << 5) | scs_120kHz: case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz120:
AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n"); AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
if(index_4msb & 0x3){ if(index_4msb & 0x3){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
...@@ -3231,7 +3240,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3231,7 +3240,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
big_m = table_38213_13_11_c3[index_4lsb]; big_m = table_38213_13_11_c3[index_4lsb];
uint32_t temp = (uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m); uint32_t temp = (uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame; type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
if((temp/num_slot_per_frame) & 0x1){ if((temp/num_slot_per_frame) & 0x1){
type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1; type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1;
...@@ -3267,12 +3276,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3267,12 +3276,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
/// MUX PATTERN 2 /// MUX PATTERN 2
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){ if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){ if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)){
// 38.213 Table 13-13 // 38.213 Table 13-13
AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n"); AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB; // sfn_c = SFN_C_EQ_SFN_SSB;
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index); type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4 switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
case 0: case 0:
type0_PDCCH_CSS_config->first_symbol_index = 0; type0_PDCCH_CSS_config->first_symbol_index = 0;
...@@ -3289,12 +3298,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3289,12 +3298,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
default: break; default: break;
} }
}else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ }else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
// 38.213 Table 13-14 // 38.213 Table 13-14
AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n"); AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB; // sfn_c = SFN_C_EQ_SFN_SSB;
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index); type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8 switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8
case 0: case 0:
type0_PDCCH_CSS_config->first_symbol_index = 0; type0_PDCCH_CSS_config->first_symbol_index = 0;
...@@ -3310,11 +3319,11 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3310,11 +3319,11 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
break; break;
case 4: case 4:
type0_PDCCH_CSS_config->first_symbol_index = 12; type0_PDCCH_CSS_config->first_symbol_index = 12;
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1; type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
break; break;
case 5: case 5:
type0_PDCCH_CSS_config->first_symbol_index = 13; type0_PDCCH_CSS_config->first_symbol_index = 13;
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1; type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
break; break;
case 6: case 6:
type0_PDCCH_CSS_config->first_symbol_index = 0; type0_PDCCH_CSS_config->first_symbol_index = 0;
...@@ -3331,12 +3340,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3331,12 +3340,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
/// MUX PATTERN 3 /// MUX PATTERN 3
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){ if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){ if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
// 38.213 Table 13-15 // 38.213 Table 13-15
AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n"); AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
// sfn_c = SFN_C_EQ_SFN_SSB; // sfn_c = SFN_C_EQ_SFN_SSB;
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index); type0_PDCCH_CSS_config->n_c = ssb_slot;
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4 switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
case 0: case 0:
type0_PDCCH_CSS_config->first_symbol_index = 4; type0_PDCCH_CSS_config->first_symbol_index = 4;
...@@ -3373,10 +3382,9 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC ...@@ -3373,10 +3382,9 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,""); AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,"");
AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,""); AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,"");
type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame; type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset; type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
return 0;
} }
/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */ /* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */
......
...@@ -126,12 +126,18 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr ...@@ -126,12 +126,18 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table); uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB); uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
NR_MIB_t *mib, frame_t frameP,
uint8_t extra_bits, NR_MIB_t *mib,
uint32_t ssb_length, uint8_t num_slot_per_frame,
uint32_t ssb_index, uint8_t ssb_subcarrier_offset,
uint32_t ssb_offset_point_a); uint16_t ssb_start_symbol,
NR_SubcarrierSpacing_t scs_ssb,
frequency_range_t frequency_range,
uint32_t ssb_index,
uint32_t ssb_offset_point_a);
uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb);
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH); int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
......
...@@ -318,7 +318,7 @@ typedef struct { ...@@ -318,7 +318,7 @@ typedef struct {
NR_TAG_Config_t *tag_Config; NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config; NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI; NR_RNTI_Value_t *cs_RNTI;
NR_MIB_t *mib; NR_MIB_t *mib;
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP]; NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP]; NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
......
...@@ -104,7 +104,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ...@@ -104,7 +104,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
LOG_D(MAC,"[L2][MAC] decode mib\n"); LOG_D(MAC,"[L2][MAC] decode mib\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
frequency_range_t frequency_range;
nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
...@@ -120,9 +121,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ...@@ -120,9 +121,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
frame = frame << 4; frame = frame << 4;
frame = frame | frame_number_4lsb; frame = frame | frame_number_4lsb;
if(ssb_length == 64){ if(ssb_length == 64){
frequency_range = FR2;
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i)); ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
}else{ }else{
frequency_range = FR1;
if(ssb_subcarrier_offset_msb){ if(ssb_subcarrier_offset_msb){
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10; ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
} }
...@@ -141,13 +144,37 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ...@@ -141,13 +144,37 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
//storing ssb index in the mac structure //storing ssb index in the mac structure
mac->mib_ssb = ssb_index; mac->mib_ssb = ssb_index;
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index, if (get_softmodem_params()->sa == 1) {
mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
// TODO these values shouldn't be taken from SCC in SA
uint8_t scs_ssb = *scc->ssbSubcarrierSpacing;
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
int scs_scaling = 1<<scs_ssb;
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
scs_scaling = scs_scaling*3;
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
scs_scaling = scs_scaling>>2;
uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
uint16_t ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index);
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config,
frame,
mac->mib,
nr_slots_per_frame[scs_ssb],
ssb_subcarrier_offset,
ssb_start_symbol,
scs_ssb,
frequency_range,
ssb_index,
absolute_diff/(12*scs_scaling)-10);
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
}
ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; // TODO: ssb_index should obtain from L1 in case Lssb != 64
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame; mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame;
mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
......
...@@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC; ...@@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC;
extern void mac_top_init_gNB(void); extern void mac_top_init_gNB(void);
extern uint8_t nfapi_mode; extern uint8_t nfapi_mode;
void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc; RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
...@@ -240,6 +240,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, ...@@ -240,6 +240,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell; cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell;
cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG; cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG;
cfg->num_tlv++; cfg->num_tlv++;
cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
cfg->num_tlv++;
switch (scc->ssb_PositionsInBurst->present) { switch (scc->ssb_PositionsInBurst->present) {
case 1 : case 1 :
...@@ -376,6 +379,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ...@@ -376,6 +379,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n"); LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
config_common(Mod_idP, config_common(Mod_idP,
ssb_SubcarrierOffset,
pdsch_AntennaPorts, pdsch_AntennaPorts,
pusch_AntennaPorts, pusch_AntennaPorts,
scc); scc);
...@@ -389,7 +393,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ...@@ -389,7 +393,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
printf("Waiting for PHY_config_req\n"); printf("Waiting for PHY_config_req\n");
} }
} }
RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10; RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10; RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
NR_PHY_Config_t phycfg; NR_PHY_Config_t phycfg;
...@@ -397,10 +402,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, ...@@ -397,10 +402,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
phycfg.CC_id = 0; phycfg.CC_id = 0;
phycfg.cfg = &RC.nrmac[Mod_idP]->config[0]; phycfg.cfg = &RC.nrmac[Mod_idP]->config[0];
phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
phycfg.cfg->num_tlv++;
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg); if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
find_SSB_and_RO_available(Mod_idP); find_SSB_and_RO_available(Mod_idP);
......
...@@ -53,35 +53,12 @@ ...@@ -53,35 +53,12 @@
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
uint8_t SSB_Slot[64]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,
20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,
30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37};
void schedule_nr_mib(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
uint8_t slots_per_frame,
int nb_periods_per_frame){
gNB_MAC_INST *gNB = RC.nrmac[module_idP]; uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) {
NR_COMMON_channels_t *cc;
nfapi_nr_dl_tti_request_t *dl_tti_request;
nfapi_nr_dl_tti_request_body_t *dl_req;
nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu;
int mib_sdu_length; int ratio;
int CC_id; switch (*scc->ssbSubcarrierSpacing) {
uint8_t beam_index = 0;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &gNB->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
int ratio;
switch (*scc->ssbSubcarrierSpacing) {
case NR_SubcarrierSpacing_kHz15: case NR_SubcarrierSpacing_kHz15:
AssertFatal(band <= 79, AssertFatal(band <= 79,
"Band %ld is not possible for SSB with 15 kHz SCS\n", "Band %ld is not possible for SSB with 15 kHz SCS\n",
...@@ -115,146 +92,197 @@ void schedule_nr_mib(module_id_t module_idP, ...@@ -115,146 +92,197 @@ void schedule_nr_mib(module_id_t module_idP,
default: default:
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n", AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
*scc->ssbSubcarrierSpacing); *scc->ssbSubcarrierSpacing);
} }
const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB
}
// scheduling MIB every 8 frames, PHY repeats it in between
void schedule_ssb(frame_t frame, sub_frame_t slot,
NR_ServingCellConfigCommon_t *scc,
nfapi_nr_dl_tti_request_body_t *dl_req,
int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) {
uint8_t beam_index = 0;
nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n");
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb;
AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = offset_pointa;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = payload;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
dl_req->nPDUs++;
LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot);
}
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame, int nb_periods_per_frame){
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc;
nfapi_nr_dl_tti_request_t *dl_tti_request;
nfapi_nr_dl_tti_request_body_t *dl_req;
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
uint8_t num_tdd_period,num_ssb;
int mib_sdu_length;
int CC_id;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &gNB->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
dl_tti_request = &gNB->DL_req[CC_id];
dl_req = &dl_tti_request->dl_tti_request_body;
// get MIB every 8 frames
if((slotP == 0) && (frameP & 7) == 0) { if((slotP == 0) && (frameP & 7) == 0) {
dl_tti_request = &gNB->DL_req[CC_id];
dl_req = &dl_tti_request->dl_tti_request_body;
mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]);
LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length); LOG_D(MAC,
"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
if (mib_sdu_length > 0) { module_idP,
LOG_D(MAC, frameP,
"Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", CC_id,
frameP, mib_sdu_length);
slotP, }
dl_req->nPDUs,
mib_sdu_length);
if ((frameP & 1023) < 80){
LOG_D(MAC,
"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
module_idP,
frameP,
CC_id,
mib_sdu_length);
}
dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
AssertFatal(scc->physCellId!=NULL,"scc->physCellId is null\n");
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
dl_req->nPDUs++;
}
// Get type0_PDCCH_CSS_config parameters int8_t ssb_period = *scc->ssb_periodicityServingCell;
NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms; uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
uint8_t gNB_xtra_byte = 0;
for (int i = 0; i < 8; i++) {
gNB_xtra_byte |= ((RC.gNB[module_idP]->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
}
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config, mib, gNB_xtra_byte, frame_parms->Lmax,
frame_parms->ssb_index, frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);
} if (ssb_period > 1) // 0 is every half frame
ssb_frame_periodicity = 1 << (ssb_period -1);
// checking if there is any SSB in slot if (!(frameP%ssb_frame_periodicity) &&
const int abs_slot = (slots_per_frame * frameP) + slotP; ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) {
const int slot_per_period = (slots_per_frame>>1)<<(*scc->ssb_periodicityServingCell); // schedule SSB only for given frames according to SSB periodicity
int eff_120_slot; // and in first half frame unless periodicity of 5ms
const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; int rel_slot;
const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; if (ssb_period == 0) // scheduling every half frame
const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap; rel_slot = slotP%(slots_per_frame>>1);
uint8_t buf = 0; else
switch (scc->ssb_PositionsInBurst->present) { rel_slot = slotP;
case 1:
// presence of ssbs possible in the first 2 slots of ssb period NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
if ((abs_slot % slot_per_period) < 2 && const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
(((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0) uint16_t offset_pointa = get_ssboffset_pointa(scc,band);
fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id); uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
break;
case 2: const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
// presence of ssbs possible in the first 4 slots of ssb period const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
if ((abs_slot % slot_per_period) < 4 && const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
(((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id); uint16_t ssb_start_symbol;
break;
case 3: switch (scc->ssb_PositionsInBurst->present) {
AssertFatal(*scc->ssbSubcarrierSpacing == case 1:
NR_SubcarrierSpacing_kHz120, // short bitmap (<3GHz) max 4 SSBs
"240kHZ subcarrier spacing currently not supported for SSBs\n"); for (int i_ssb=0; i_ssb<4; i_ssb++) {
if ((abs_slot % slot_per_period) < 8) { if ((shortBitmap->buf[0]>>(7-i_ssb))&0x01) {
eff_120_slot = slotP; ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
if((abs_slot % slot_per_period) < 3) // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
buf = longBitmap->buf[0]; if ((ssb_start_symbol/14) == rel_slot){
else schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
buf = longBitmap->buf[1]; fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
} else if ((abs_slot % slot_per_period) < 18) { if (get_softmodem_params()->sa == 1) {
eff_120_slot = slotP - 10; get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
if((abs_slot % slot_per_period) < 13) frameP,
buf = longBitmap->buf[2]; mib,
else slots_per_frame,
buf = longBitmap->buf[3]; ssbSubcarrierOffset,
} else if ((abs_slot % slot_per_period) < 28) { ssb_start_symbol,
eff_120_slot = slotP - 20; scs,
if((abs_slot % slot_per_period) < 23) FR1,
buf = longBitmap->buf[4]; i_ssb,
else offset_pointa);
buf = longBitmap->buf[5]; gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
} else if ((abs_slot % slot_per_period) < 38) { }
eff_120_slot = slotP - 30; }
if((abs_slot % slot_per_period) < 33) }
buf = longBitmap->buf[6]; }
else break;
buf = longBitmap->buf[7]; case 2:
} // medium bitmap (<6GHz) max 8 SSBs
if ((eff_120_slot>=0) && (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0)) { for (int i_ssb=0; i_ssb<8; i_ssb++) {
AssertFatal(((buf >> (6 - (eff_120_slot << 1))) & 3)<3,"We only support 1 ssb per slot max in FR2 for the moment\n"); if ((mediumBitmap->buf[0]>>(7-i_ssb))&0x01) {
fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id); ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
} // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
break; if ((ssb_start_symbol/14) == rel_slot){
default: schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n", fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
scc->ssb_PositionsInBurst->present); if (get_softmodem_params()->sa == 1) {
} get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
// For FR2 beam ssb association at the beginning of every SSB period frameP,
if((scc->ssb_PositionsInBurst->present==3) && (abs_slot%slot_per_period == 0)){ mib,
uint8_t i_ssb,num_tdd_period; slots_per_frame,
uint8_t num_ssb = 0; ssbSubcarrierOffset,
for (int i=0; i<64; i++){ ssb_start_symbol,
i_ssb=((longBitmap->buf[i/8])>>(7-(i%8)))&1; scs,
if(i_ssb==1){ FR1,
num_tdd_period = SSB_Slot[i]/(slots_per_frame/nb_periods_per_frame); i_ssb,
gNB->tdd_beam_association[num_tdd_period]=num_ssb; offset_pointa);
num_ssb++; gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
} }
}
}
}
break;
case 3:
// long bitmap FR2 max 64 SSBs
num_ssb = 0;
for (int i_ssb=0; i_ssb<63; i_ssb++) {
if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) {
ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
if ((ssb_start_symbol/14) == rel_slot){
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
num_tdd_period = rel_slot/(slots_per_frame/nb_periods_per_frame);
gNB->tdd_beam_association[num_tdd_period]=i_ssb;
num_ssb++;
AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n");
if (get_softmodem_params()->sa == 1) {
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
frameP,
mib,
slots_per_frame,
ssbSubcarrierOffset,
ssb_start_symbol,
scs,
FR2,
i_ssb,
offset_pointa);
gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
}
}
}
}
break;
default:
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
scc->ssb_PositionsInBurst->present);
} }
} }
} }
...@@ -265,14 +293,22 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe ...@@ -265,14 +293,22 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe
//---------------------------------------- //----------------------------------------
} }
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) { void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id) {
AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
NR_SubcarrierSpacing_kHz240,
"240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");
uint16_t *vrb_map = cc[CC_id].vrb_map; uint16_t *vrb_map = cc[CC_id].vrb_map;
for (int rb = 0; rb < 20; rb++) for (int rb = 0; rb < 20; rb++)
vrb_map[rbStart + rb] = 1; vrb_map[rbStart + rb] = 15<<symStart;
} }
void schedule_control_sib1(module_id_t module_id, void schedule_control_sib1(module_id_t module_id,
int CC_id, int CC_id,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation, int time_domain_allocation,
uint8_t mcsTableIdx, uint8_t mcsTableIdx,
uint8_t mcs, uint8_t mcs,
...@@ -286,7 +322,6 @@ void schedule_control_sib1(module_id_t module_id, ...@@ -286,7 +322,6 @@ void schedule_control_sib1(module_id_t module_id,
if (gNB_mac->sched_ctrlCommon == NULL){ if (gNB_mac->sched_ctrlCommon == NULL){
gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon)); gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon));
gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space)); gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset)); gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp)); gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space); fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space);
...@@ -313,8 +348,8 @@ void schedule_control_sib1(module_id_t module_id, ...@@ -313,8 +348,8 @@ void schedule_control_sib1(module_id_t module_id,
AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n"); AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs; const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb; int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
// Calculate number of symbols // Calculate number of symbols
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
...@@ -359,6 +394,7 @@ void schedule_control_sib1(module_id_t module_id, ...@@ -359,6 +394,7 @@ void schedule_control_sib1(module_id_t module_id,
void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
nfapi_nr_dl_tti_request_body_t *dl_req, nfapi_nr_dl_tti_request_body_t *dl_req,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
uint32_t TBS, uint32_t TBS,
int StartSymbolIndex, int StartSymbolIndex,
int NrOfSymbols) { int NrOfSymbols) {
...@@ -381,6 +417,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, ...@@ -381,6 +417,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
scc, scc,
bwp); bwp);
// TODO: This assignment should be done in function nr_configure_pdcch()
pdcch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config->num_rbs;
pdcch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config->cset_start_rb;
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
...@@ -394,8 +434,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, ...@@ -394,8 +434,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
pdsch_pdu_rel15->rnti = SI_RNTI; pdsch_pdu_rel15->rnti = SI_RNTI;
pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++; pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
pdsch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs; pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb; pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
if (bwp->bwp_Common->genericParameters.cyclicPrefix) { if (bwp->bwp_Common->genericParameters.cyclicPrefix) {
...@@ -452,7 +492,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, ...@@ -452,7 +492,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
// frequency domain assignment // frequency domain assignment
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0( dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs); pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs);
dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation; dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs; dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs;
...@@ -507,52 +547,80 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ...@@ -507,52 +547,80 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
uint8_t candidate_idx = 0; uint8_t candidate_idx = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
if( (frameP%2 == gNB_mac->type0_PDCCH_CSS_config.sfn_c) && (slotP == gNB_mac->type0_PDCCH_CSS_config.n_0) && (gNB_mac->type0_PDCCH_CSS_config.num_rbs > 0) ) { int L_max;
switch (scc->ssb_PositionsInBurst->present) {
case 1:
L_max = 4;
break;
case 2:
L_max = 8;
break;
case 3:
L_max = 64;
break;
default:
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
scc->ssb_PositionsInBurst->present);
}
for (int i=0; i<L_max; i++) {
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[i];
LOG_D(MAC,"> SIB1 transmission\n"); if((frameP%2 == type0_PDCCH_CSS_config->sfn_c) &&
(slotP == type0_PDCCH_CSS_config->n_0) &&
(type0_PDCCH_CSS_config->num_rbs > 0) &&
(type0_PDCCH_CSS_config->active == true)) {
// Get SIB1 LOG_D(MAC,"> SIB1 transmission\n");
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
LOG_D(MAC,"SIB1: \n");
for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
// Configure sched_ctrlCommon for SIB1 // Get SIB1
schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length); uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
LOG_D(MAC,"SIB1: \n");
for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
// Calculate number of symbols // Configure sched_ctrlCommon for SIB1
int startSymbolIndex, nrOfSymbols; schedule_control_sib1(module_idP, CC_id, type0_PDCCH_CSS_config, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
// Calculate number of PRB_DMRS // Calculate number of symbols
uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; int startSymbolIndex, nrOfSymbols;
uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), // Calculate number of PRB_DMRS
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3; uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols); nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols);
// Data to be transmitted const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES); nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
tx_req->PDU_length = TBS; // Data to be transmitted
tx_req->PDU_index = gNB_mac->pdu_index[0]++; bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
tx_req->num_TLV = 1; memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
tx_req->TLVs[0].length = TBS + 2;
gNB_mac->TX_req[CC_id].Number_of_PDUs++; tx_req->PDU_length = TBS;
gNB_mac->TX_req[CC_id].SFN = frameP; tx_req->PDU_index = gNB_mac->pdu_index[0]++;
gNB_mac->TX_req[CC_id].Slot = slotP; tx_req->num_TLV = 1;
tx_req->TLVs[0].length = TBS + 2;
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
gNB_mac->TX_req[CC_id].SFN = frameP;
gNB_mac->TX_req[CC_id].Slot = slotP;
type0_PDCCH_CSS_config->active = false;
}
} }
} }
...@@ -41,6 +41,7 @@ void set_cset_offset(uint16_t); ...@@ -41,6 +41,7 @@ void set_cset_offset(uint16_t);
void mac_top_init_gNB(void); void mac_top_init_gNB(void);
void config_common(int Mod_idP, void config_common(int Mod_idP,
int ssb_SubcarrierOffset,
int pdsch_AntennaPorts, int pdsch_AntennaPorts,
int pusch_AntennaPorts, int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc NR_ServingCellConfigCommon_t *scc
...@@ -72,6 +73,7 @@ void nr_schedule_ue_spec(module_id_t module_id, ...@@ -72,6 +73,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
void schedule_control_sib1(module_id_t module_id, void schedule_control_sib1(module_id_t module_id,
int CC_id, int CC_id,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation, int time_domain_allocation,
uint8_t mcsTableIdx, uint8_t mcsTableIdx,
uint8_t mcs, uint8_t mcs,
...@@ -367,7 +369,7 @@ int binomial(int n, int k); ...@@ -367,7 +369,7 @@ int binomial(int n, int k);
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id); void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id);
/* \brief Function to indicate a received SDU on ULSCH. /* \brief Function to indicate a received SDU on ULSCH.
......
...@@ -611,6 +611,8 @@ typedef struct gNB_MAC_INST_s { ...@@ -611,6 +611,8 @@ typedef struct gNB_MAC_INST_s {
int pusch_target_snrx10; int pusch_target_snrx10;
/// Pucch target SNR /// Pucch target SNR
int pucch_target_snrx10; int pucch_target_snrx10;
/// Subcarrier Offset
int ssb_SubcarrierOffset;
/// Common cell resources /// Common cell resources
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX]; NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
/// current PDU index (BCH,DLSCH) /// current PDU index (BCH,DLSCH)
...@@ -677,7 +679,7 @@ typedef struct gNB_MAC_INST_s { ...@@ -677,7 +679,7 @@ typedef struct gNB_MAC_INST_s {
NR_UE_sched_ctrl_t *sched_ctrlCommon; NR_UE_sched_ctrl_t *sched_ctrlCommon;
NR_CellGroupConfig_t *secondaryCellGroupCommon; NR_CellGroupConfig_t *secondaryCellGroupCommon;
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
} gNB_MAC_INST; } gNB_MAC_INST;
......
...@@ -23,6 +23,7 @@ gNBs = ...@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0; ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1; pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200; pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200;
......
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