Commit c9265000 authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/NR_4_layers_MIMO' into integration_2024_w13

parents 883724b9 f2c83054
......@@ -85,11 +85,9 @@ static const int tables_5_3_2[5][12] = {
{32, 66, 132, 264, -1, -1, -1, -1, -1, -1, -1, -1} // 120FR2
};
int get_supported_band_index(int scs, int band, int n_rbs)
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs)
{
int scs_index = scs;
if (band > 256)
scs_index++;
int scs_index = scs + freq_range;
for (int i = 0; i < 12; i++) {
if(n_rbs == tables_5_3_2[scs_index][i])
return i;
......@@ -224,7 +222,7 @@ bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_
// 38.101-1 section 6.2.2
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
int index = get_nr_table_idx(nr_band, scs);
int bw_index = get_supported_band_index(scs, nr_band, nb_ul);
int bw_index = get_supported_band_index(scs, nr_band > 256 ? FR2 : FR1, nb_ul);
int band_size_khz = get_supported_bw_mhz(nr_band > 256 ? FR2 : FR1, bw_index) * 1000;
float limit = frame_type == TDD ? 0.04 : 0.03;
float rel_bw = (float) (2 * band_size_khz) / (float) (nr_bandtable[index].ul_max + nr_bandtable[index].ul_min);
......@@ -829,18 +827,6 @@ void get_samplerate_and_bw(int mu,
}
}
void get_K1_K2(int N1, int N2, int *K1, int *K2)
{
// num of allowed k1 and k2 according to 5.2.2.2.1-3 and -4 in 38.214
if(N2 == N1 || N1 == 2)
*K1 = 2;
else if (N2 == 1)
*K1 = 5;
else
*K1 = 3;
*K2 = N2 > 1 ? 2 : 1;
}
// from start symbol index and nb or symbols to symbol occupation bitmap in a slot
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) {
return ((1<<nrOfSymbols)-1)<<startSymbolIndex;
......
......@@ -194,11 +194,10 @@ void SLIV2SL(int SLIV,int *S,int *L);
int get_dmrs_port(int nl, uint16_t dmrs_ports);
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
int get_nb_periods_per_frame(uint8_t tdd_period);
int get_supported_band_index(int scs, int band, int n_rbs);
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
void get_K1_K2(int N1, int N2, int *K1, int *K2);
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type);
int get_supported_bw_mhz(frequency_range_t frequency_range, int bw_index);
int get_supported_band_index(int scs, frequency_range_t freq_range, int n_rbs);
void get_samplerate_and_bw(int mu,
int n_rb,
int8_t threequarter_fs,
......
......@@ -60,7 +60,7 @@ Furthermore, the gNB and UE support
- Single and multiple DMRS symbols
- PTRS support
- Support for 1, 2 and 4 TX antennas
- Support for up to 2 layers (currently limited to DMRS configuration type 2)
- Support for up to 2 layers
- Support for 256 QAM
* NR-CSIRS Generation of sequence at PHY
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
......
......@@ -513,7 +513,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
}
fp->threequarter_fs = 0;
int bw_index = get_supported_band_index(mu, fp->nr_band, N_RB_DL);
int bw_index = get_supported_band_index(mu, fp->nr_band > 256 ? FR2 : FR1, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index);
nr_init_frame_parms(gNB_config, fp);
......
......@@ -1015,7 +1015,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu) {
nfapi_nr_pucch_pdu_t* pucch_pdu)
{
c16_t **rxdataF = gNB->common_vars.rxdataF;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
......
......@@ -162,7 +162,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
else fp->nr_band = 78;
fp->threequarter_fs= 0;
int bw_index = get_supported_band_index(mu, fp->nr_band, N_RB_DL);
int bw_index = get_supported_band_index(mu, fp->nr_band > 256 ? FR2 : FR1, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(fp->nr_band > 256 ? FR2 : FR1, bw_index);
fp->ofdm_offset_divisor = UINT_MAX;
......
......@@ -494,6 +494,9 @@ typedef struct{
uint8_t li_bitlen[8];
uint8_t pmi_x1_bitlen[8];
uint8_t pmi_x2_bitlen[8];
uint8_t pmi_i11_bitlen[8];
uint8_t pmi_i12_bitlen[8];
uint8_t pmi_i13_bitlen[8];
uint8_t cqi_bitlen[8];
} CSI_Meas_bitlen_t;
......
......@@ -119,7 +119,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR;
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
mac->nr_band,
mac->nr_band > 256 ? FR2 : FR1,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
......@@ -141,7 +141,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL;
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
mac->nr_band,
mac->nr_band > 256 ? FR2 : FR1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
......@@ -263,7 +263,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;
int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
mac->nr_band,
mac->nr_band > 256 ? FR2 : FR1,
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
......@@ -288,7 +288,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac,
mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
*frequencyInfoUL->frequencyBandList->list.array[0],
*frequencyInfoUL->frequencyBandList->list.array[0] > 256 ? FR2 : FR1,
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
......
......@@ -141,7 +141,7 @@ static void sl_prepare_phy_config(int module_id,
AssertFatal(carriercfg, "SCS_SpecificCarrier cannot be NULL");
int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing,
sl_band,
sl_band > 256 ? FR2 : FR1,
carriercfg->carrierBandwidth);
phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index);
......
This diff is collapsed.
......@@ -130,6 +130,46 @@ uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl,
}
// Table 5.2.2.2.1-3 and Table 5.2.2.2.1-4 in 38.214
void get_k1_k2_indices(const int layers, const int N1, const int N2, const int i13, int *k1, int *k2)
{
AssertFatal(layers > 0 && layers < 5, "Number of layers %d not supported\n", layers);
*k1 = 0;
*k2 = 0;
if (layers == 2) {
if (N2 == 1)
*k1 = i13;
else if (N1 == N2) {
*k1 = i13 & 1;
*k2 = i13 >> 1;
}
else {
*k1 = (i13 & 1) + (i13 == 3);
*k2 = (i13 == 2);
}
}
if (layers == 3 || layers == 4) {
if (N2 == 1)
*k1 = i13 + 1;
else if (N1 == 2 && N2 == 2) {
*k1 = !(i13 & 1);
*k2 = (i13 > 0);
}
else {
if (i13 == 0)
*k1 = 1;
if (i13 == 1)
*k2 = 1;
if (i13 == 2) {
*k1 = 1;
*k2 = 1;
}
if (i13 == 3)
*k1 = 2;
}
}
}
uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
const NR_UE_info_t *UE,
nr_dci_format_t dci_format,
......@@ -138,14 +178,16 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
{
if (dci_format == NR_DL_DCI_FORMAT_1_0 || nrmac->identity_pm || xp_pdsch_antenna_ports == 1)
return 0; //identity matrix (basic 5G configuration handled by PMI report is with XP antennas)
const NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
const int report_id = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id;
const nr_csi_report_t *csi_report = &UE->csi_report_template[report_id];
const int N1 = csi_report->N1;
const int N2 = csi_report->N2;
const int antenna_ports = (N1 * N2) << 1;
const int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1;
if (antenna_ports < 2)
return 0; // single antenna port
int x1 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1;
const int x2 = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2;
LOG_D(NR_MAC,"PMI report: x1 %d x2 %d layers: %d\n", x1, x2, layers);
......@@ -160,8 +202,37 @@ uint16_t get_pm_index(const gNB_MAC_INST *nrmac,
// elements from n+1 to m for 2 layers etc.
if (antenna_ports == 2)
return 1 + prev_layers_size + x2; // 0 for identity matrix
else
AssertFatal(1==0,"More than 2 antenna ports not yet supported\n");
else {
int idx = layers - 1;
// the order of i1x in X1 report needs to be verified
// the standard is not very clear (Table 6.3.1.1.2-7 in 38.212)
// it says: PMI wideband information fields X1 , from left to right
int bitlen = csi_report->csi_meas_bitlen.pmi_i13_bitlen[idx];
if (layers == 1 && bitlen != 0) {
LOG_E(NR_MAC, "Invalid i13 bit length %d for single layer! It should be 0\n", bitlen);
return 0;
}
const int i13 = x1 & ((1 << bitlen) - 1);
x1 >>= bitlen;
bitlen = csi_report->csi_meas_bitlen.pmi_i12_bitlen[idx];
const int i12 = x1 & ((1 << bitlen) - 1);
x1 >>= bitlen;
bitlen = csi_report->csi_meas_bitlen.pmi_i11_bitlen[idx];
const int i11 = x1 & ((1 << bitlen) - 1);
const int i2 = x2;
int k1, k2;
get_k1_k2_indices(layers, N1, N2, i13, &k1, &k2); // get indices k1 and k2 for PHY matrix (not actual k1 and k2 values)
const int O2 = N2 == 1 ? 1 : 4;
int O1 = 4; //Horizontal beam oversampling = 4 for more than 2 antenna ports
int max_i2 = 0;
int lay_index = 0;
max_i2 = layers == 1 ? 4 : 2;
int K1, K2;
get_K1_K2(N1, N2, &K1, &K2, layers);
// computing precoding matrix index according to rule set in allocation function init_codebook_gNB
lay_index = i2 + (i11 * max_i2) + (i12 * max_i2 * N1 * O1) + (k1 * max_i2 * N1 * O1 * N2 * O2) + (k2 * max_i2 * N1 * O1 * N2 * O2 * K1);
return 1 + prev_layers_size + lay_index;
}
}
uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx)
......
......@@ -761,12 +761,12 @@ static int evaluate_ri_report(uint8_t *payload,
NR_UE_sched_ctrl_t *sched_ctrl)
{
uint8_t ri_index = pickandreverse_bits(payload, ri_bitlen, cumul_bits);
int count=0;
for (int i=0; i<8; i++) {
if ((ri_restriction>>i)&0x01) {
int count = 0;
for (int i = 0; i < 8; i++) {
if ((ri_restriction >> i) & 0x01) {
if(count == ri_index) {
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri = i;
LOG_D(MAC,"CSI Reported Rank %d\n", i+1);
LOG_D(MAC,"CSI Reported Rank %d\n", i + 1);
return i;
}
count++;
......@@ -821,8 +821,8 @@ static uint8_t evaluate_pmi_report(uint8_t *payload,
//in case of 2 port CSI configuration x1 is empty and the information bits are in x2
int temp_pmi = pickandreverse_bits(payload, tot_bitlen, cumul_bits);
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1 = temp_pmi&((1<<x1_bitlen)-1);
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2 = (temp_pmi>>x1_bitlen)&((1<<x2_bitlen)-1);
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1 = temp_pmi & ((1 << x1_bitlen) - 1);
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2 = (temp_pmi >> x1_bitlen) & ((1 << x2_bitlen) - 1);
LOG_D(MAC,"PMI Report: X1 %d X2 %d\n",
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
......
......@@ -36,6 +36,7 @@
#include "common/ngran_types.h"
void set_cset_offset(uint16_t);
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
void mac_top_init_gNB(ngran_node_t node_type,
NR_ServingCellConfigCommon_t *scc,
......
This diff is collapsed.
......@@ -44,7 +44,8 @@
#include "NR_SecurityConfig.h"
#include "NR_CellGroupConfig.h"
#define NR_MAX_SUPPORTED_DL_LAYERS 2
#define NR_MAX_SUPPORTED_DL_LAYERS 4
void rrc_init_nr_srb_param(NR_LCHAN_DESC *chan);
void rrc_gNB_process_SgNBAdditionRequest(
const protocol_ctxt_t *const ctxt_pP,
......
......@@ -226,7 +226,7 @@ static int get_ssb_arfcn(const f1ap_served_cell_info_t *cell_info, const NR_MIB_
else
AssertFatal(false, "Invalid absoluteFrequencyPointA: %d\n", dl_arfcn);
int bw_index = get_supported_band_index(scs, band, get_dl_bw(cell_info));
int bw_index = get_supported_band_index(scs, band > 256 ? FR2 : FR1, get_dl_bw(cell_info));
int band_size_hz = get_supported_bw_mhz(band > 256 ? FR2 : FR1, bw_index) * 1000 * 1000;
uint32_t ssb_arfcn = to_nrarfcn(band, freqssb, scs, band_size_hz);
......
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