Commit 630f8ac2 authored by Melissa Elkadi's avatar Melissa Elkadi

Putting all CM code in one file

This commit includes reorganization of
all of the SISO/MIMO channel modelling
support being moved into a single CM
file. Furthermore, it includes a bug
fix for the number of MCS simulation
tables (29 total, 0-28).
parent 5944b212
......@@ -1926,6 +1926,7 @@ set (MAC_SRC_UE
set (MAC_NR_SRC_UE
${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c
${NR_UE_MAC_DIR}/config_ue.c
${NR_UE_MAC_DIR}/mac_vars.c
${NR_UE_MAC_DIR}/main_ue_nr.c
......
......@@ -907,7 +907,7 @@ typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_rela
#define MCS_COUNT 28
#define MCS_COUNT 29
#define MCS_TABLE_LENGTH_MAX 64
......
......@@ -66,17 +66,6 @@ queue_t nr_tx_req_queue;
queue_t nr_ul_dci_req_queue;
queue_t nr_ul_tti_req_queue;
static slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
//static int get_mcs_from_sinr(float sinr);
//static int get_cqi_from_mcs(void);
static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index);
//static bool did_drop_transport_block(int slot, uint16_t rnti);
static float get_bler_val(uint8_t mcs, int sinr);
static bool should_drop_transport_block(int slot, uint16_t rnti);
static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
static inline bool is_channel_modeling(void);
void nrue_init_standalone_socket(int tx_port, int rx_port)
{
{
......@@ -939,7 +928,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea
return;
}
static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request)
void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request)
{
int count_sent = 0;
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
......@@ -1343,245 +1332,3 @@ void RCconfig_nr_ue_L1(void) {
}
}
}
/*
static int get_mcs_from_sinr(float sinr)
{
if (sinr < (nr_bler_data[0].bler_table[0][0]))
{
LOG_D(NR_MAC, "The SINR found is smaller than first MCS table\n");
return 0;
}
if (sinr > (nr_bler_data[NR_NUM_MCS-1].bler_table[nr_bler_data[NR_NUM_MCS-1].length - 1][0]))
{
LOG_D(NR_MAC, "The SINR found is larger than last MCS table\n");
return NR_NUM_MCS-1;
}
for (int n = NR_NUM_MCS-1; n >= 0; n--)
{
CHECK_INDEX(nr_bler_data, n);
float largest_sinr = (nr_bler_data[n].bler_table[nr_bler_data[n].length - 1][0]);
float smallest_sinr = (nr_bler_data[n].bler_table[0][0]);
if (sinr < largest_sinr && sinr > smallest_sinr)
{
LOG_D(NR_MAC, "The SINR found in MCS %d table\n", n);
return n;
}
}
LOG_E(NR_MAC, "Unable to get an MCS value.\n");
abort();
}
*/
/*
static int get_cqi_from_mcs(void)
{
static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15};
assert(NUM_ELEMENTS(mcs_to_cqi) == NR_NUM_MCS);
int slot = 0;
while (slot < NUM_NFAPI_SLOT)
{
if (slot_rnti_mcs[slot].latest)
{
int num_pdus = slot_rnti_mcs[slot].num_pdus;
if (num_pdus <= 0)
{
LOG_E(NR_MAC, "%s: slot_rnti_mcs[%d].num_pdus = 0\n", __FUNCTION__, slot);
abort();
}
CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
int mcs = get_mcs_from_sinr(slot_rnti_mcs[slot].sinr);
CHECK_INDEX(mcs_to_cqi, mcs);
int cqi = mcs_to_cqi[mcs];
LOG_D(NR_MAC, "SINR: %f -> MCS: %d -> CQI: %d\n", slot_rnti_mcs[slot].sinr, mcs, cqi);
return cqi;
}
slot++;
}
LOG_E(NR_MAC, "Unable to get CQI value because no MCS found\n");
abort();
}
*/
static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index)
{
if (pdu == NULL)
{
LOG_E(NR_MAC,"PDU NULL\n");
abort();
}
/* This function is executed for every pdsch pdu type in a dl_tti_request. We save
the assocaited MCS and RNTI value for each. The 'index' passed in is a count of
how many times we have called this function for a particular dl_tti_request. It
allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/
for (int i = 0; i < NUM_NFAPI_SLOT; i++)
{
slot_rnti_mcs[i].latest = false;
}
CHECK_INDEX(slot_rnti_mcs[slot].rnti, index);
CHECK_INDEX(slot_rnti_mcs[slot].mcs, index);
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index);
slot_rnti_mcs[slot].rnti[index] = pdu->rnti;
slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0];
slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0];
slot_rnti_mcs[slot].drop_flag[index] = false;
slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus
slot_rnti_mcs[slot].latest = true;
LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot);
return;
}
/*
static bool did_drop_transport_block(int slot, uint16_t rnti)
{
int num_pdus = slot_rnti_mcs[slot].num_pdus;
if (num_pdus <= 0)
{
LOG_E(MAC, "Problem, the PDU size is <= 0. We dropped this packet\n");
return true;
}
CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
for (int n = 0; n < num_pdus; n++)
{
if (slot_rnti_mcs[slot].rnti[n] == rnti && slot_rnti_mcs[slot].drop_flag[n])
{
return true;
}
}
return false;
}
*/
static float get_bler_val(uint8_t mcs, int sinr)
{
// 4th col = dropped packets, 5th col = total packets
float bler_val = 0.0;
CHECK_INDEX(nr_bler_data, mcs);
LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr,
(int)(nr_bler_data[mcs].bler_table[0][0] * 10),
(int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)
);
if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10))
{
LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs);
bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5];
return bler_val;
}
if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10))
{
LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs);
bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5];
return bler_val;
}
// Loop through bler table to find sinr_index
for (int i = 0; i < nr_bler_data[mcs].length; i++)
{
int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10);
if (temp_sinr == sinr)
{
bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
return bler_val;
}
// Linear interpolation when SINR is between indices
if (temp_sinr > sinr)
{
float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5];
float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2);
return ((bler_val1 + bler_val2) / 2);
}
}
LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n");
abort();
}
static inline bool is_channel_modeling(void)
{
/* TODO: For now we enable channel modeling based on the node_number.
Replace with a command line option to enable/disable channel modeling.
The LTE UE will crash when channel modeling is conducted for NSA
mode. It does not crash for LTE mode. We have not implemented channel
modeling for NSA mode yet. For now, we ensure only do do channel modeling
in LTE/NR mode. */
return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa;
}
static bool should_drop_transport_block(int slot, uint16_t rnti)
{
if (!is_channel_modeling())
{
return false;
}
/* We want to avoid dropping setup messages because this would be pathological. */
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
if (mac->ra.ra_state < RA_SUCCEEDED)
{
LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state);
return false;
}
/* Get block error rate (bler_val) from table based on every saved
MCS and SINR to be used as the cutoff rate for dropping packets.
Generate random uniform vairable to compare against bler_val. */
int num_pdus = slot_rnti_mcs[slot].num_pdus;
assert(slot < 20 && slot >= 0);
LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n",
rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr);
assert(num_pdus > 0);
CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
int n = 0;
uint8_t mcs = 99;
for (n = 0; n < num_pdus; n++)
{
if (slot_rnti_mcs[slot].rnti[n] == rnti)
{
mcs = slot_rnti_mcs[slot].mcs[n];
}
if (mcs != 99)
{
/* Use MCS to get the bler value. Since there can be multiple MCS
values for a particular slot, we verify that all PDUs are not
flagged for drop before returning. If even one is flagged for drop
we return immediately because we drop the entire packet. */
LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n",
slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr);
float bler_val;
if (slot_rnti_mcs[slot].rvIndex[n] != 0)
bler_val = 0;
else
bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10)));
double drop_cutoff = ((double) rand() / (RAND_MAX));
assert(drop_cutoff <= 1);
LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]);
if (drop_cutoff <= bler_val)
{
slot_rnti_mcs[slot].drop_flag[n] = true;
LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot);
return slot_rnti_mcs[slot].drop_flag[n];
}
}
}
if (mcs == 99)
{
LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n);
abort();
}
return false;
}
......@@ -40,45 +40,12 @@
#include "openair2/PHY_INTERFACE/queue_t.h"
#include "nfapi_nr_interface_scf.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "NR_Packet_Drop.h"
#define NR_NUM_MCS 29
#define NUM_SINR 100
#define NUM_BLER_COL 13
#define NUM_NFAPI_SLOT 20
#define NR_NUM_LAYER 1
extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
typedef struct nr_phy_channel_params_t
{
uint16_t sfn_slot;
uint16_t message_id;
uint16_t nb_of_sinrs;
float sinr[NR_NUM_LAYER];
// Incomplete, need all channel parameters
} nr_phy_channel_params_t;
typedef struct
{
uint8_t slot;
uint16_t rnti[256];
uint8_t mcs[256];
uint8_t rvIndex[256];
float sinr;
uint16_t num_pdus;
bool drop_flag[256];
bool latest;
} slot_rnti_mcs_s;
typedef struct
{
uint16_t length;
float bler_table[NUM_SINR][NUM_BLER_COL];
} nr_bler_struct;
extern nr_bler_struct nr_bler_data[NR_NUM_MCS];
typedef enum {
ONLY_PUSCH,
NOT_PUSCH,
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include "openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h"
#include "executables/softmodem-common.h"
#include "NR_MAC_UE/mac_proto.h"
slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index)
{
if (pdu == NULL)
{
LOG_E(NR_MAC,"PDU NULL\n");
abort();
}
/* This function is executed for every pdsch pdu type in a dl_tti_request. We save
the assocaited MCS and RNTI value for each. The 'index' passed in is a count of
how many times we have called this function for a particular dl_tti_request. It
allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/
for (int i = 0; i < NUM_NFAPI_SLOT; i++)
{
slot_rnti_mcs[i].latest = false;
}
CHECK_INDEX(slot_rnti_mcs[slot].rnti, index);
CHECK_INDEX(slot_rnti_mcs[slot].mcs, index);
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index);
slot_rnti_mcs[slot].rnti[index] = pdu->rnti;
slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0];
slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0];
slot_rnti_mcs[slot].drop_flag[index] = false;
slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus
slot_rnti_mcs[slot].latest = true;
LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot);
return;
}
float get_bler_val(uint8_t mcs, int sinr)
{
// 4th col = dropped packets, 5th col = total packets
nr_bler_struct nr_bler_data[NR_NUM_MCS];
float bler_val = 0.0;
CHECK_INDEX(nr_bler_data, mcs);
LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr,
(int)(nr_bler_data[mcs].bler_table[0][0] * 10),
(int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)
);
if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10))
{
LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs);
bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5];
return bler_val;
}
if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10))
{
LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs);
bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5];
return bler_val;
}
// Loop through bler table to find sinr_index
for (int i = 0; i < nr_bler_data[mcs].length; i++)
{
int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10);
if (temp_sinr == sinr)
{
bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
return bler_val;
}
// Linear interpolation when SINR is between indices
if (temp_sinr > sinr)
{
float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5];
float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5];
LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2);
return ((bler_val1 + bler_val2) / 2);
}
}
LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n");
abort();
}
bool is_channel_modeling(void)
{
/* TODO: For now we enable channel modeling based on the node_number.
Replace with a command line option to enable/disable channel modeling.
The LTE UE will crash when channel modeling is conducted for NSA
mode. It does not crash for LTE mode. We have not implemented channel
modeling for NSA mode yet. For now, we ensure only do do channel modeling
in LTE/NR mode. */
return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa;
}
bool should_drop_transport_block(int slot, uint16_t rnti)
{
if (!is_channel_modeling())
{
return false;
}
/* We want to avoid dropping setup messages because this would be pathological. */
NR_UE_MAC_INST_t *mac = get_mac_inst(0);
if (mac->ra.ra_state < RA_SUCCEEDED)
{
LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state);
return false;
}
/* Get block error rate (bler_val) from table based on every saved
MCS and SINR to be used as the cutoff rate for dropping packets.
Generate random uniform vairable to compare against bler_val. */
int num_pdus = slot_rnti_mcs[slot].num_pdus;
assert(slot < 20 && slot >= 0);
LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n",
rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr);
assert(num_pdus > 0);
CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus);
CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus);
CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus);
int n = 0;
uint8_t mcs = 99;
for (n = 0; n < num_pdus; n++)
{
if (slot_rnti_mcs[slot].rnti[n] == rnti)
{
mcs = slot_rnti_mcs[slot].mcs[n];
}
if (mcs != 99)
{
/* Use MCS to get the bler value. Since there can be multiple MCS
values for a particular slot, we verify that all PDUs are not
flagged for drop before returning. If even one is flagged for drop
we return immediately because we drop the entire packet. */
LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n",
slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr);
float bler_val;
if (slot_rnti_mcs[slot].rvIndex[n] != 0)
bler_val = 0;
else
bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10)));
double drop_cutoff = ((double) rand() / (RAND_MAX));
assert(drop_cutoff <= 1);
LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]);
if (drop_cutoff <= bler_val)
{
slot_rnti_mcs[slot].drop_flag[n] = true;
LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot);
return slot_rnti_mcs[slot].drop_flag[n];
}
}
}
if (mcs == 99)
{
LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n);
abort();
}
return false;
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __NR_CHAN_MODEL_H__
#define __NR_CHAN_MODEL_H__
#include <platform_types.h>
#include <nfapi_nr_interface_scf.h>
#include <openair1/PHY/thread_NR_UE.h>
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#define NR_NUM_MCS 29
#define NUM_SINR 100
#define NUM_BLER_COL 13
#define NUM_NFAPI_SLOT 20
#define NR_NUM_LAYER 1
#define MAX_CHAN_PARAMS 256
typedef struct nr_phy_channel_params_t
{
uint16_t sfn_slot;
uint16_t message_id;
uint16_t nb_of_sinrs;
float sinr[NR_NUM_LAYER];
} nr_phy_channel_params_t;
typedef struct
{
uint8_t slot;
uint16_t rnti[MAX_CHAN_PARAMS];
uint8_t mcs[MAX_CHAN_PARAMS];
uint8_t rvIndex[MAX_CHAN_PARAMS];
float sinr;
uint16_t num_pdus;
bool drop_flag[MAX_CHAN_PARAMS];
bool latest;
} slot_rnti_mcs_s;
typedef struct
{
uint16_t length;
float bler_table[NUM_SINR][NUM_BLER_COL];
} nr_bler_struct;
void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index);
void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request);
float get_bler_val(uint8_t mcs, int sinr);
bool should_drop_transport_block(int slot, uint16_t rnti);
bool is_channel_modeling(void);
#endif
......@@ -1956,7 +1956,7 @@ static int get_mcs_from_sinr(float sinr)
static int get_cqi_from_mcs(void)
{
static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15};
static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
assert(NUM_ELEMENTS(mcs_to_cqi) == NUM_MCS);
int sf = 0;
while(sf < NUM_NFAPI_SUBFRAME)
......
......@@ -21,7 +21,7 @@
//#include "openair1/PHY/LTE_TRANSPORT/defs.h"
#include "queue_t.h"
#define NUM_MCS 28
#define NUM_MCS 29
#define NUM_SINR 100
#define NUM_BLER_COL 13
#define LTE_NUM_LAYER 1
......
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