diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
index 2bfd09509c..0da833b3f7 100644
--- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
index fc32d65a23..b8a601ce41 100644
--- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
index daee5486c1..7be25a24fa 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -22,6 +22,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
@@ -250,7 +251,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
- pusch_proc_threads = 8;
+ pusch_proc_threads = 6;
}
);
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 016c76dc06..b0511f63cc 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1330,7 +1330,8 @@
(Test3: 30kHz SCS, 273 PRBs, Prach format A2),
(Test4: 30kHz SCS, 106 PRBs, Prach format 0),
(Test5: 120kHz SCS, 32 PRBs, Prach format A2),
- (Test6: 120kHz SCS, 66 PRBs, Prach format A2)
+ (Test6: 120kHz SCS, 66 PRBs, Prach format A2),
+ (Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1342,8 +1343,9 @@
-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 32 -R 32 -m 3 -c52
- -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
- nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6
+ -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
+ -a -s -30 -n 100 -R 66 -m 3 -c52 -H
+ nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7
PRACH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md
index 73ae18351f..5f9299f0ef 100644
--- a/doc/TESTING_GNB_W_COTS_UE.md
+++ b/doc/TESTING_GNB_W_COTS_UE.md
@@ -44,10 +44,11 @@ Our code might not work with all 5G phones yet, but we are constantly improving
* Oppo Reno 5G
* Samsung A90 5G
-* Google Pixel 5G
+* Google Pixel 5G (note1)
* Simcom SIMCOM8200EA
* 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
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 184a3a0e07..a92f433560 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -468,15 +468,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
PHY_VARS_gNB *gNB;
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);
}
for (inst=0; instnumerology_index;
- uint8_t half_frame_index = fp->half_frame_bit;
- uint8_t i_ssb = fp->ssb_index;
int symbol = 0;
uint8_t n, n_temp;
nr_ssb_type_e type = fp->ssb_type;
@@ -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);
}
- if (half_frame_index)
- symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
-
return symbol;
}
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index 9c474264c8..2db0ccc258 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -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);
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_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);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index 7b0a0150d3..b7de182ab7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -30,7 +30,7 @@
* \warning
*/
-#include
+
#include "nr_dci.h"
#include "nr_dlsch.h"
#include "nr_sch_dmrs.h"
@@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
// compute rb_offset and n_prb based on frequency allocation
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
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;
- 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;
- }
+ cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
for (int d=0;dnumDlDci;d++) {
/*The coreset is initialised
diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
index bd1278b2eb..0bc04e3047 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c
@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
///Payload generation
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
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 Lmax = frame_parms->Lmax;
for (int i=0; issb_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;
for (int i=0; i<4; i++)
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index 0ba02c6bac..2c4c0b9e14 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
#endif
not_found = 1;
+ nr_fill_du(N_ZC,prach_root_sequence_map);
preamble_index0 = preamble_index;
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
// preamble index and find the corresponding cyclic shift
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 8368c1dbec..2f6c4324b0 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -182,7 +182,10 @@ typedef struct {
int16_t sqrt_rho_b;
} NR_gNB_DLSCH_t;
-
+typedef struct {
+ bool active;
+ nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
+} NR_gNB_SSB_t;
typedef struct {
int frame;
@@ -711,10 +714,10 @@ typedef struct PHY_VARS_gNB_s {
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_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];
- 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_gNB_COMMON common_vars;
NR_gNB_PRACH prach_vars;
diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c
index d65d3b54bb..88f3dca070 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.c
+++ b/openair1/SCHED_NR/fapi_nr_l1.c
@@ -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",
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);
- memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
+ uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
+
+ 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,
@@ -166,14 +173,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
gNB->dlsch[i][0]->harq_mask=0;
}
- gNB->pbch_configured=0;
-
for (int i=0;idl_tti_request_body.dl_tti_pdu_list[i];
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
switch (dl_tti_pdu->PDUType) {
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
- gNB->pbch_configured=1;
if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
@@ -257,4 +261,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
}
-}
\ No newline at end of file
+}
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 674ae82cc3..d44c8641a6 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -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);
}
-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;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
int **txdataF = gNB->common_vars.txdataF;
- uint8_t ssb_index, ssb_per_slot=0, n_hf;
- uint16_t ssb_start_symbol, rel_slot;
+ uint8_t ssb_index, n_hf;
+ uint16_t ssb_start_symbol;
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
uint16_t slots_per_hf = (fp->slots_per_frame)>>1;
- n_hf = fp->half_frame_bit;
+ if (slotssb_table.ssb_period.value == 0) {
- if (slotsymbols_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] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
+ bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
+ bch[2] = (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));
}
- // to set a effective slot number in the half frame where the SSB is supposed to be
- rel_slot = (n_hf)? (slot-slots_per_hf) : 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,
- &gNB->ssb_pdu,
- gNB->nr_pbch_interleaver,
- &txdataF[0][txdataF_offset],
- AMP,
- ssb_start_symbol,
- n_hf, frame, cfg, fp);
-
- // SSB beamforming is handled at PHY
- // currently our PHY does not support switching more than once a slot.
- if (ssb_per_slot>1) {
- LOG_W(PHY,"beamforming currently not supported for more than one SSB per slot\n");
- }
- else if (ssb_per_slot==1) {
- 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;jsymbols_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;
- }
- }
- }
+ // 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;jsymbols_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,
int frame,int slot,
int do_meas) {
@@ -153,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
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;
-
- 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) &&
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
@@ -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);
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
- nr_common_signal_procedures(gNB,frame, slot);
+ for (int i=0; iLmax; i++) {
+ 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);
@@ -468,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
(pucch->frame == frame_rx) &&
(pucch->slot == slot_rx) ) {
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) &&
(symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
for (rb=0; rbprb_size; rb++) {
diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h
index 24885f1bb4..e0cf20d862 100644
--- a/openair1/SCHED_NR/sched_nr.h
+++ b/openair1/SCHED_NR/sched_nr.h
@@ -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_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 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_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);
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 9614b4b649..0a7ae96e09 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -173,6 +173,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
}
void config_common(int Mod_idP,
+ int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
@@ -679,7 +680,7 @@ int main(int argc, char **argv)
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
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);
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
fix_scc(scc,ssb_bitmap);
@@ -858,7 +859,8 @@ int main(int argc, char **argv)
// generate signal
AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
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
rrc.carrier.MIB = (uint8_t*) malloc(4);
@@ -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 );
}
if (run_initial_sync)
- nr_common_signal_procedures(gNB,frame,slot);
+ nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
else
phy_procedures_gNB_TX(gNB,frame,slot,0);
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index a3c2501197..ee74909a9e 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -119,7 +119,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
int main(int argc, char **argv)
{
char c;
- int i,aa;//,l;
+ int i,aa,start_symbol;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
double cfo=0;
uint8_t snr1set=0;
@@ -426,29 +426,28 @@ int main(int argc, char **argv)
switch (mu) {
case 1:
- scs = 30000;
- if (N_RB_DL == 217) {
- fs = 122.88e6;
- bw = 80e6;
-
- }
- else if (N_RB_DL == 245) {
- fs = 122.88e6;
- bw = 90e6;
- }
- else if (N_RB_DL == 273) {
- fs = 122.88e6;
- bw = 100e6;
- }
- else if (N_RB_DL == 106) {
- fs = 61.44e6;
- bw = 40e6;
- }
- else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
- break;
-
-
+ scs = 30000;
+ frame_parms->Lmax = 8;
+ if (N_RB_DL == 217) {
+ fs = 122.88e6;
+ bw = 80e6;
+ }
+ else if (N_RB_DL == 245) {
+ fs = 122.88e6;
+ bw = 90e6;
+ }
+ else if (N_RB_DL == 273) {
+ fs = 122.88e6;
+ bw = 100e6;
+ }
+ else if (N_RB_DL == 106) {
+ fs = 61.44e6;
+ bw = 40e6;
+ }
+ else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
+ break;
case 3:
+ frame_parms->Lmax = 64;
scs = 120000;
if (N_RB_DL == 66) {
fs = 122.88e6;
@@ -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);
break;
}
+
// cfo with respect to sub-carrier spacing
eps = cfo/scs;
@@ -510,7 +510,6 @@ int main(int argc, char **argv)
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(r_re[i],frame_length_complex_samples*sizeof(int));
-
}
if (pbch_file_fd!=NULL) {
@@ -536,60 +535,68 @@ int main(int argc, char **argv)
}
nr_gold_pbch(UE);
+
// generate signal
if (input_fd==NULL) {
- gNB->pbch_configured = 1;
-
- gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
- for (int slot=0;slotslots_per_frame;slot++) {
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
- memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
-
- nr_common_signal_procedures (gNB,frame,slot);
+ for (i=0; iLmax; i++) {
+ if((SSB_positions >> i) & 0x01) {
- for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
- if (cyclic_prefix_type == 1) {
- PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
- &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- frame_parms->ofdm_symbol_size,
- 12,
- frame_parms->nb_prefix_samples,
- CYCLIC_PREFIX);
- } else {
- /* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
- &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- 14,
- frame_parms);*/
- PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
- (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- frame_parms->ofdm_symbol_size,
- 1,
- frame_parms->nb_prefix_samples0,
- CYCLIC_PREFIX);
-
- apply_nr_rotation(frame_parms,
- (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
- slot,
- 0,
- 1,
- frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
- PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
- (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,
- 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);
- }
- }
+ gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
+ gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
+
+ start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
+ int slot = start_symbol/14;
+
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
+ memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
+
+ nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
+
+ for (aa=0; aaframe_parms.nb_antennas_tx; aa++) {
+ if (cyclic_prefix_type == 1) {
+ PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+ &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ frame_parms->ofdm_symbol_size,
+ 12,
+ frame_parms->nb_prefix_samples,
+ CYCLIC_PREFIX);
+ } else {
+ /*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
+ &txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ 14,
+ frame_parms);*/
+ PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
+ (int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ frame_parms->ofdm_symbol_size,
+ 1,
+ frame_parms->nb_prefix_samples0,
+ CYCLIC_PREFIX);
+
+ apply_nr_rotation(frame_parms,
+ (int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
+ slot,
+ 0,
+ 1,
+ frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
+
+ PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
+ (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,
+ 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);
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);
@@ -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);
UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used
if (fread(txdata[0],
- sizeof(int32_t),
- frame_length_complex_samples,
- input_fd) != frame_length_complex_samples) {
+ sizeof(int32_t),
+ frame_length_complex_samples,
+ input_fd) != frame_length_complex_samples) {
printf("error reading from file\n");
//exit(-1);
}
@@ -684,10 +691,9 @@ int main(int argc, char **argv)
UE->rx_offset=0;
uint8_t ssb_index = 0;
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);
+ UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
- 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; isymbol_offset+4; i++) {
nr_slot_fep(UE,
&proc,
@@ -716,7 +722,7 @@ int main(int argc, char **argv)
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
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("ret %d\n", payload_ret);
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 74ca8d9184..efbc40cd55 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -205,7 +205,7 @@ int main(int argc, char **argv){
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) {
case 'a':
printf("Running AWGN simulation\n");
@@ -218,6 +218,10 @@ int main(int argc, char **argv){
config_index = atoi(optarg);
break;
+ case 'l':
+ loglvl = atoi(optarg);
+ break;
+
case 'r':
msg1_frequencystart = atoi(optarg);
break;
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 381dce11b2..67cf5051ef 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#define TABLE_38213_13_1_NUM_INDEXES 15
#define TABLE_38213_13_2_NUM_INDEXES 14
@@ -418,14 +419,6 @@ typedef enum {
NR_RNTI_MCS_C,
} 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 {
bw_5MHz = 0x1,
bw_10MHz = 0x2,
@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
uint32_t ssb_length;
uint32_t ssb_index;
uint32_t cset_start_rb;
+ bool active;
} NR_Type0_PDCCH_CSS_config_t;
#endif /*__LAYER2_MAC_H__ */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 514d7eacdb..941bd04877 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -36,6 +36,13 @@
#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};
// 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,
return valid;
}
-uint32_t get_ssb_slot(uint32_t ssb_index){
- // this function now only support f <= 3GHz
- return ssb_index & 0x3 ;
+uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb) {
- // 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,
- NR_MIB_t *mib,
- uint8_t extra_bits,
- uint32_t ssb_length,
- uint32_t ssb_index,
- uint32_t ssb_offset_point_a) {
+void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+ frame_t frameP,
+ NR_MIB_t *mib,
+ uint8_t num_slot_per_frame,
+ uint8_t ssb_subcarrier_offset,
+ 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
- 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;
+ NR_SubcarrierSpacing_t scs_pdcch;
+
+ channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104
+
+ if (frequency_range == FR2) {
+ if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
+ scs_pdcch = NR_SubcarrierSpacing_kHz60;
+ else
+ scs_pdcch = NR_SubcarrierSpacing_kHz120;
+ }
+ else {
+ frequency_range = FR1;
+ if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
+ scs_pdcch = NR_SubcarrierSpacing_kHz15;
+ else
+ scs_pdcch = NR_SubcarrierSpacing_kHz30;
+ }
- type0_PDCCH_CSS_config->ssb_length = ssb_length;
type0_PDCCH_CSS_config->ssb_index = ssb_index;
- type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused);
+ type0_PDCCH_CSS_config->frame = frameP;
- uint16_t frame_number_4lsb = 0;
- for (int i=0; i<4; i++) {
- frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
- }
-
- uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
- uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset;
-
- type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4;
- type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb;
-
- 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
- subcarrier_spacing_t scs_pdcch;
- if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
- scs_pdcch = scs_15kHz;
- }else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
- scs_pdcch = scs_30kHz;
- }
+ uint8_t ssb_slot = ssb_start_symbol/14;
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
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
type0_PDCCH_CSS_config->rb_offset = -1;
// type0-pdcch coreset
- switch( (scs_ssb << 5) | scs_pdcch ){
- case (scs_15kHz << 5) | scs_15kHz :
+ switch( (scs_ssb << 3) | scs_pdcch ){
+ case (NR_SubcarrierSpacing_kHz15 << 5) | NR_SubcarrierSpacing_kHz15:
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->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
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
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");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
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
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
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)){
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;
@@ -3102,7 +3111,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
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)){
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
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
}else{ ; }
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");
if(index_4msb & 0x7){
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
}
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");
if(index_4msb & 0x3){
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
}
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");
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
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
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
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");
if(index_4msb & 0x3){
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
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];
- 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<ssb_index*big_m);
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
if((temp/num_slot_per_frame) & 0x1){
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
/// 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
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
// 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
case 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
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
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
// 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
case 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
break;
case 4:
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;
case 5:
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;
case 6:
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
/// 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
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
// 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
case 0:
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
AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,"");
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<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;
- return 0;
}
/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 3e21131b69..741b4e4799 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -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_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,
- NR_MIB_t *mib,
- uint8_t extra_bits,
- uint32_t ssb_length,
- uint32_t ssb_index,
- uint32_t ssb_offset_point_a);
+void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
+ frame_t frameP,
+ NR_MIB_t *mib,
+ uint8_t num_slot_per_frame,
+ uint8_t ssb_subcarrier_offset,
+ 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);
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 3e299d291e..933286f95a 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -318,7 +318,7 @@ typedef struct {
NR_TAG_Config_t *tag_Config;
NR_PHR_Config_t *phr_Config;
NR_RNTI_Value_t *cs_RNTI;
- NR_MIB_t *mib;
+ NR_MIB_t *mib;
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index cfcaac6c4b..8b8fc4e0c2 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -104,7 +104,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
LOG_D(MAC,"[L2][MAC] decode mib\n");
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
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,
frame = frame << 4;
frame = frame | frame_number_4lsb;
if(ssb_length == 64){
+ frequency_range = FR2;
for (int i=0; i<3; i++)
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
}else{
+ frequency_range = FR1;
if(ssb_subcarrier_offset_msb){
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
}
@@ -141,13 +144,37 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
//storing ssb index in the mac structure
mac->mib_ssb = ssb_index;
- get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index,
- mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
+ if (get_softmodem_params()->sa == 1) {
+
+ // 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<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.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index caa56bdff9..d0a8037307 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC;
extern void mac_top_init_gNB(void);
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];
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,
cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell;
cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG;
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) {
case 1 :
@@ -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");
config_common(Mod_idP,
+ ssb_SubcarrierOffset,
pdsch_AntennaPorts,
pusch_AntennaPorts,
scc);
@@ -389,7 +393,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
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]->pucch_target_snrx10 = pucch_tgt_snrx10;
NR_PHY_Config_t phycfg;
@@ -397,10 +402,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
phycfg.CC_id = 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);
find_SSB_and_RO_available(Mod_idP);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 0ceff015e7..444eabb789 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -53,35 +53,12 @@
#include "executables/softmodem-common.h"
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];
- 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;
+uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) {
- int mib_sdu_length;
- int CC_id;
- 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) {
+ int ratio;
+ switch (*scc->ssbSubcarrierSpacing) {
case NR_SubcarrierSpacing_kHz15:
AssertFatal(band <= 79,
"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,
default:
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
*scc->ssbSubcarrierSpacing);
- }
+ }
- // scheduling MIB every 8 frames, PHY repeats it in between
+ 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
+
+}
+
+
+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) {
- 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]);
- LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length);
-
- if (mib_sdu_length > 0) {
- LOG_D(MAC,
- "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n",
- frameP,
- 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
- NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms;
- 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);
-
+ LOG_D(MAC,
+ "[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
+ module_idP,
+ frameP,
+ CC_id,
+ mib_sdu_length);
}
- // checking if there is any SSB in slot
- const int abs_slot = (slots_per_frame * frameP) + slotP;
- const int slot_per_period = (slots_per_frame>>1)<<(*scc->ssb_periodicityServingCell);
- int eff_120_slot;
- const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
- const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
- const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
- uint8_t buf = 0;
- switch (scc->ssb_PositionsInBurst->present) {
- case 1:
- // presence of ssbs possible in the first 2 slots of ssb period
- if ((abs_slot % slot_per_period) < 2 &&
- (((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
- fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
- break;
- case 2:
- // presence of ssbs possible in the first 4 slots of ssb period
- if ((abs_slot % slot_per_period) < 4 &&
- (((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
- fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
- break;
- case 3:
- AssertFatal(*scc->ssbSubcarrierSpacing ==
- NR_SubcarrierSpacing_kHz120,
- "240kHZ subcarrier spacing currently not supported for SSBs\n");
- if ((abs_slot % slot_per_period) < 8) {
- eff_120_slot = slotP;
- if((abs_slot % slot_per_period) < 3)
- buf = longBitmap->buf[0];
- else
- buf = longBitmap->buf[1];
- } else if ((abs_slot % slot_per_period) < 18) {
- eff_120_slot = slotP - 10;
- if((abs_slot % slot_per_period) < 13)
- buf = longBitmap->buf[2];
- else
- buf = longBitmap->buf[3];
- } else if ((abs_slot % slot_per_period) < 28) {
- eff_120_slot = slotP - 20;
- if((abs_slot % slot_per_period) < 23)
- buf = longBitmap->buf[4];
- else
- buf = longBitmap->buf[5];
- } 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
- buf = longBitmap->buf[7];
- }
- if ((eff_120_slot>=0) && (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0)) {
- AssertFatal(((buf >> (6 - (eff_120_slot << 1))) & 3)<3,"We only support 1 ssb per slot max in FR2 for the moment\n");
- fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id);
- }
- break;
- default:
- AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
- scc->ssb_PositionsInBurst->present);
- }
- // For FR2 beam ssb association at the beginning of every SSB period
- if((scc->ssb_PositionsInBurst->present==3) && (abs_slot%slot_per_period == 0)){
- uint8_t i_ssb,num_tdd_period;
- uint8_t num_ssb = 0;
- for (int i=0; i<64; i++){
- i_ssb=((longBitmap->buf[i/8])>>(7-(i%8)))&1;
- if(i_ssb==1){
- num_tdd_period = SSB_Slot[i]/(slots_per_frame/nb_periods_per_frame);
- gNB->tdd_beam_association[num_tdd_period]=num_ssb;
- num_ssb++;
- }
+ int8_t ssb_period = *scc->ssb_periodicityServingCell;
+ uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
+
+ if (ssb_period > 1) // 0 is every half frame
+ ssb_frame_periodicity = 1 << (ssb_period -1);
+
+ if (!(frameP%ssb_frame_periodicity) &&
+ ((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) {
+ // schedule SSB only for given frames according to SSB periodicity
+ // and in first half frame unless periodicity of 5ms
+ int rel_slot;
+ if (ssb_period == 0) // scheduling every half frame
+ rel_slot = slotP%(slots_per_frame>>1);
+ else
+ rel_slot = slotP;
+
+ NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
+ const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+ uint16_t offset_pointa = get_ssboffset_pointa(scc,band);
+ uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
+
+ const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
+ const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
+ const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
+
+ uint16_t ssb_start_symbol;
+
+ switch (scc->ssb_PositionsInBurst->present) {
+ case 1:
+ // short bitmap (<3GHz) max 4 SSBs
+ for (int i_ssb=0; i_ssb<4; i_ssb++) {
+ if ((shortBitmap->buf[0]>>(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);
+ 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,
+ FR1,
+ i_ssb,
+ offset_pointa);
+ gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
+ }
+ }
+ }
+ }
+ break;
+ case 2:
+ // medium bitmap (<6GHz) max 8 SSBs
+ for (int i_ssb=0; i_ssb<8; i_ssb++) {
+ if ((mediumBitmap->buf[0]>>(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);
+ 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,
+ FR1,
+ i_ssb,
+ offset_pointa);
+ 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
//----------------------------------------
}
-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;
+
for (int rb = 0; rb < 20; rb++)
- vrb_map[rbStart + rb] = 1;
+ vrb_map[rbStart + rb] = 15<sched_ctrlCommon == NULL){
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->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->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space);
@@ -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");
- const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
- int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+ const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
+ int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
// Calculate number of symbols
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,
void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
nfapi_nr_dl_tti_request_body_t *dl_req,
+ NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
uint32_t TBS,
int StartSymbolIndex,
int NrOfSymbols) {
@@ -381,6 +417,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
scc,
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];
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;
@@ -394,8 +434,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
pdsch_pdu_rel15->rnti = SI_RNTI;
pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
- pdsch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
- pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
+ pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
+ pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
if (bwp->bwp_Common->genericParameters.cyclicPrefix) {
@@ -452,7 +492,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
// frequency domain assignment
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.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)
uint8_t candidate_idx = 0;
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);
+ }
- LOG_D(MAC,"> SIB1 transmission\n");
+ for (int i=0; itype0_PDCCH_CSS_config[i];
- // Configure sched_ctrlCommon for SIB1
- schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
+ 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)) {
- // Calculate number of symbols
- int startSymbolIndex, nrOfSymbols;
- 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);
+ LOG_D(MAC,"> SIB1 transmission\n");
- // Calculate number of PRB_DMRS
- uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
- 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);
+ // Get SIB1
+ 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;isched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
- 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;
+ // Configure sched_ctrlCommon for SIB1
+ schedule_control_sib1(module_idP, CC_id, type0_PDCCH_CSS_config, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
- nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
- nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols);
+ // Calculate number of symbols
+ int startSymbolIndex, nrOfSymbols;
+ 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);
- const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
- nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
+ // Calculate number of PRB_DMRS
+ uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
+ 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);
- // Data to be transmitted
- bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
- memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
+ const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
+ 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;
- tx_req->PDU_length = TBS;
- tx_req->PDU_index = gNB_mac->pdu_index[0]++;
- 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;
+ nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
+ nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols);
+
+ const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
+ nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
+
+ // Data to be transmitted
+ bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
+ memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
+
+ tx_req->PDU_length = TBS;
+ tx_req->PDU_index = gNB_mac->pdu_index[0]++;
+ 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;
+ }
}
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 7f9e2a9a8d..f552b6c606 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -41,6 +41,7 @@ void set_cset_offset(uint16_t);
void mac_top_init_gNB(void);
void config_common(int Mod_idP,
+ int ssb_SubcarrierOffset,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
NR_ServingCellConfigCommon_t *scc
@@ -72,6 +73,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
void schedule_control_sib1(module_id_t module_id,
int CC_id,
+ NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
@@ -367,7 +369,7 @@ int binomial(int n, int k);
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.
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 8452ca3c4c..d9869e7a7b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -611,6 +611,8 @@ typedef struct gNB_MAC_INST_s {
int pusch_target_snrx10;
/// Pucch target SNR
int pucch_target_snrx10;
+ /// Subcarrier Offset
+ int ssb_SubcarrierOffset;
/// Common cell resources
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
/// current PDU index (BCH,DLSCH)
@@ -677,7 +679,7 @@ typedef struct gNB_MAC_INST_s {
NR_UE_sched_ctrl_t *sched_ctrlCommon;
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;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
index 39ee3c4a61..477240a3a0 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;