Merge remote-tracking branch 'origin/develop' into NR_UE_SA

This commit is contained in:
francescomani
2021-08-30 17:55:38 +02:00
76 changed files with 1928 additions and 686 deletions
@@ -236,9 +236,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -231,10 +231,11 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 6;
}
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
+4 -4
View File
@@ -97,7 +97,7 @@
<desc>Ping: 20pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
</testCase>
<testCase id="050001">
@@ -105,7 +105,7 @@
<desc>Ping: 100pings in 20sec</desc>
<id>idefix</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>50</ping_packetloss_threshold>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
</testCase>
<testCase id="070000">
@@ -114,7 +114,7 @@
<iperf_args>-u -b 20M -t 60</iperf_args>
<direction>DL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>3</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
@@ -124,7 +124,7 @@
<iperf_args>-u -b 3M -t 60</iperf_args>
<direction>UL</direction>
<id>idefix</id>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_packetloss_threshold>1</iperf_packetloss_threshold>
<iperf_profile>single-ue</iperf_profile>
</testCase>
+2
View File
@@ -85,6 +85,7 @@
#include "T.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "executables/softmodem-common.h"
#include <nfapi/oai_integration/nfapi_pnf.h>
#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h>
#include <PHY/NR_ESTIMATION/nr_ul_estimation.h>
@@ -534,6 +535,7 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/
gNB->prach_energy_counter = 0;
gNB->prb_interpolation = get_softmodem_params()->prb_interpolation;
}
+6 -2
View File
@@ -253,6 +253,7 @@ void init_tpools(uint8_t nun_dlsch_threads) {
}
static void get_options(void) {
nrUE_params.ofdm_offset_divisor = 8;
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
config_process_cmdline( cmdline_params,numparams,NULL);
@@ -318,8 +319,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
UE->rf_map.card = card_offset;
UE->rf_map.chain = CC_id + chain_offset;
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction);
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n, do_prb_interpolation %d\n",
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction, UE->prb_interpolation);
// Set FP variables
@@ -330,6 +331,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs);
fp->ofdm_offset_divisor = nrUE_params.ofdm_offset_divisor;
}
void init_openair0(void) {
@@ -487,6 +490,7 @@ int main( int argc, char **argv ) {
}
init_symbol_rotation(&UE[CC_id]->frame_parms);
init_timeshift_rotation(&UE[CC_id]->frame_parms);
init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
#ifdef FR2_TEST
+5 -1
View File
@@ -8,7 +8,8 @@
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization"
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization\n"
#define CONFIG_HLP_OFFSET_DIV "Divisor for computing OFDM symbol offset in Rx chain (num samples in CP/<the value>). Default value is 8. To set the sample offset to 0, set this value ~ 10e6\n"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
when calling config_get or config_getlist functions */
@@ -29,6 +30,7 @@
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
{"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \
@@ -60,12 +62,14 @@
{"r" , CONFIG_HLP_PRB_SA, 0, iptr:&(fp->N_RB_DL), defintval:106, TYPE_UINT, 0}, \
{"s" , CONFIG_HLP_SSC, 0, u16ptr:&(fp->ssb_start_subcarrier), defintval:516, TYPE_UINT16,0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&(UE->prb_interpolation), defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
}
typedef struct {
uint64_t optmask; //mask to store boolean config options
uint32_t ofdm_offset_divisor; // Divisor for sample offset computation for each OFDM symbol
uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
tpool_t Tpool; // thread pool
} nrUE_params_t;
+4
View File
@@ -72,6 +72,7 @@ extern "C"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n"
#define CONFIG_HLP_PRBINTER "Do PRB based averaging of channel estimates. Frequency domain linear interpolation by default\n"
#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
@@ -119,6 +120,7 @@ extern "C"
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
#define PRB_INTERPOLATION softmodem_params.prb_interpolation
#define NFAPI softmodem_params.nfapi
#define NON_STOP softmodem_params.non_stop
@@ -153,6 +155,7 @@ extern int usrp_tx_thread;
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
{"usrp-tx-thread-config",CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
@@ -246,6 +249,7 @@ typedef struct {
int hw_timing_advance;
uint32_t send_dmrs_sync;
int use_256qam_table;
int prb_interpolation;
uint8_t nfapi;
int non_stop;
} softmodem_params_t;
+3
View File
@@ -459,6 +459,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
nr_init_frame_parms(gNB_config, fp);
fp->ofdm_offset_divisor = UINT_MAX;
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
}
@@ -510,7 +511,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
// }
RC.gNB[Mod_id]->configured = 1;
fp->ofdm_offset_divisor = RC.gNB[Mod_id]->ofdm_offset_divisor;
init_symbol_rotation(fp);
init_timeshift_rotation(fp);
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
+1 -1
View File
@@ -124,7 +124,7 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch,
AssertFatal( pusch, "pusch==0" );
for (int i=0; i<NR_MAX_NB_LAYERS; i++) {
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t *));
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear(NR_MAX_PUSCH_ENCODED_LENGTH*sizeof(int32_t));
}
}
+1 -1
View File
@@ -49,7 +49,7 @@ void PHY_ofdm_mod(int *input,
void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms);
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot);
void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
+17
View File
@@ -745,6 +745,23 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
}
}
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp)
{
for (int i = 0; i < fp->ofdm_symbol_size; i++) {
double poff = -i * 2.0 * M_PI * 144.0 / 2048.0 / fp->ofdm_offset_divisor;
double exp_re = cos(poff);
double exp_im = sin(-poff);
fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767);
fp->timeshift_symbol_rotation[i*2+1] = (int16_t)round(exp_im * 32767);
if (i < 10)
LOG_I(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i,
fp->timeshift_symbol_rotation[i*2],
fp->timeshift_symbol_rotation[i*2+1],
poff);
}
}
int nr_layer_precoder(int16_t **datatx_F_precoding, char *prec_matrix, uint8_t n_layers, int32_t re_offset)
{
int32_t precodatatx_F = 0;
+2
View File
@@ -117,6 +117,8 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp);
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF,
int slot,
+55 -13
View File
@@ -63,20 +63,62 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA
}
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms)
void nr_normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,NR_DL_FRAME_PARMS *frame_parms, uint32_t slot)
{
PHY_ofdm_mod(txdataF, // input
txdata, // output
frame_parms->ofdm_symbol_size,
1, // number of symbols
frame_parms->nb_prefix_samples0, // number of prefix samples
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0, // output
frame_parms->ofdm_symbol_size,
nsymb - 1,
frame_parms->nb_prefix_samples, // number of prefix samples
CYCLIC_PREFIX);
// This function works only slot wise. For more generic symbol generation refer nr_feptx0()
if (frame_parms->numerology_index != 0) { // case where numerology != 0
if (!(slot%(frame_parms->slots_per_subframe/2))) {
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
nsymb - 1,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
else {
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
nsymb,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
}
else { // numerology = 0, longer CP for every 7th symbol
PHY_ofdm_mod(txdataF,
txdata,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size,
txdata + frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
6,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF + 7*frame_parms->ofdm_symbol_size,
txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) +
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0,
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod(txdataF + 8*frame_parms->ofdm_symbol_size,
txdata + 6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples) +
2*(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0),
frame_parms->ofdm_symbol_size,
6,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
}
}
void PHY_ofdm_mod(int *input, /// pointer to complex input
+27 -11
View File
@@ -107,7 +107,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
rx_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= nb_prefix_samples / 8;
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
#ifdef DEBUG_FEP
// if (ue->frame <100)
@@ -157,6 +157,15 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
frame_parms->ofdm_symbol_size,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
1,
frame_parms->ofdm_symbol_size,
15);
}
#ifdef DEBUG_FEP
@@ -292,14 +301,15 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
unsigned int slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
// offset of first OFDM symbol
int32_t rxdata_offset = slot_offset + nb_prefix_samples0;
// offset of n-th OFDM symbol
rxdata_offset += symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples);
unsigned int rxdata_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0);
unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol;
for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rxdata_offset += (idx_symb%(0x7<<frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rxdata_offset += frame_parms->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rxdata_offset -= nb_prefix_samples / 8;
rxdata_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
int16_t *rxdata_ptr;
@@ -333,9 +343,6 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size],
1);
// clear DC carrier from OFDM symbols
rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0;
return 0;
}
@@ -349,7 +356,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
for (int symbol=0;symbol<nsymb;symbol++) {
for (int symbol=first_symbol;symbol<nsymb;symbol++) {
uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
@@ -359,5 +366,14 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
length,
15);
int16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
1,
length,
15);
}
}
@@ -39,23 +39,22 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
{
int i, aa, max_pos = 0, max_val = 0;
int max_pos = 0, max_val = 0;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_PUSCH *gNB_pusch_vars = gNB->pusch_vars[UE_id];
int32_t **ul_ch_estimates_time = gNB_pusch_vars->ul_ch_estimates_time;
int sync_pos = frame_parms->nb_prefix_samples / 8;
for (i = 0; i < frame_parms->ofdm_symbol_size; i++) {
const int sync_pos = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
int temp = 0;
for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
short Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
short Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((int16_t*)ul_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ul_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
if (temp > max_val) {
max_pos = i;
max_val = temp;
@@ -65,7 +64,6 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
if (max_pos > frame_parms->ofdm_symbol_size/2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
return max_pos - sync_pos;
}
@@ -31,11 +31,13 @@
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "executables/softmodem-common.h"
//#define DEBUG_CH
//#define DEBUG_PUSCH
#define NO_INTERP 1
#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y)))
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
@@ -187,8 +189,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#endif
//if ((gNB->frame_parms.N_RB_UL&1)==0) {
if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1){
if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1 && gNB->prb_interpolation == 0){
LOG_D(PHY,"PUSCH estimation DMRS type 1, Freq-domain interpolation");
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -212,7 +214,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//for (int i= 0; i<8; i++)
@@ -243,7 +245,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch);
@@ -277,12 +279,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//for (int i= 0; i<16; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ul_ch += 8;
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt+=2) {
for (pilot_cnt=3; pilot_cnt<(6*nb_rb_pusch-3); pilot_cnt += 2) {
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -295,7 +297,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
//printf("ul_ch addr %p\n",ul_ch);
@@ -315,10 +317,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//for (int i= 0; i<16; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ul_ch += 8;
}
@@ -337,7 +339,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//for (int i= 0; i<8; i++)
//printf("ul_ch addr %p %d\n", ul_ch+i, *(ul_ch+i));
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
@@ -353,10 +355,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch,
8);
pil+=2;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ul_ch+=8;
ul_ch += 8;
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
@@ -425,15 +427,15 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_PUSCH
ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI+=2) {
for(uint8_t idxI=0; idxI<16; idxI += 2) {
printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
}
printf("%d\n",idxP);
}
#endif
}
else { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type2 && gNB->prb_interpolation == 0) { //pusch_dmrs_type2 |p_r,p_l,d,d,d,d,p_r,p_l,d,d,d,d|
LOG_D(PHY,"PUSCH estimation DMRS type 2, Freq-domain interpolation");
// Treat first DMRS specially (left edge)
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
@@ -441,12 +443,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ul_ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
pil+=2;
ul_ch+=2;
pil += 2;
ul_ch += 2;
re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size;
ch_offset++;
for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt+=6){
for (re_cnt = 1; re_cnt < (nb_rb_pusch*NR_NB_SC_PER_RB) - 5; re_cnt += 6){
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
@@ -456,8 +458,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[0] = ch_l[0];
ul_ch[1] = ch_l[1];
pil+=2;
ul_ch+=2;
pil += 2;
ul_ch += 2;
ch_offset++;
multadd_real_four_symbols_vector_complex_scalar(filt8_ml2,
@@ -476,17 +478,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch_r,
ul_ch);
//for (int re_idx = 0; re_idx < 8; re_idx+=2)
//for (int re_idx = 0; re_idx < 8; re_idx += 2)
//printf("ul_ch = %d + j*%d\n", ul_ch[re_idx], ul_ch[re_idx+1]);
ul_ch+=8;
ch_offset+=4;
ul_ch += 8;
ch_offset += 4;
ul_ch[0] = ch_r[0];
ul_ch[1] = ch_r[1];
pil+=2;
ul_ch+=2;
pil += 2;
ul_ch += 2;
ch_offset++;
re_offset = (re_offset + 1)%gNB->frame_parms.ofdm_symbol_size;
@@ -502,7 +504,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch[0] = ch_l[0];
ul_ch[1] = ch_l[1];
ul_ch+=2;
ul_ch += 2;
ch_offset++;
multadd_real_four_symbols_vector_complex_scalar(filt8_rr1,
@@ -518,6 +520,385 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ul_ch_128[0] = _mm_slli_epi16 (ul_ch_128[0], 2);
}
else if (pusch_pdu->dmrs_config_type == pusch_dmrs_type1) {// this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 6 DMRS REs and use a common value for the whole PRB
LOG_D(PHY,"PUSCH estimation DMRS type 1, no Freq-domain interpolation");
int32_t ch_0, ch_1;
// First PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 6;
ch[1] = ch_1 / 6;
#if NO_INTERP
for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch;
ul_ch+=24;
#else
multadd_real_vector_complex_scalar(filt8_avlip0,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip1,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip2,
ch,
ul_ch,
8);
ul_ch -= 24;
#endif
for (pilot_cnt=6; pilot_cnt<6*(nb_rb_pusch-1); pilot_cnt += 6) {
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 6;
ch[1] = ch_1 / 6;
#if NO_INTERP
for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch;
ul_ch+=24;
#else
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip4,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip5,
ch,
ul_ch,
8);
ul_ch -= 16;
#endif
}
// Last PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+2) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 6;
ch[1] = ch_1 / 6;
#if NO_INTERP
for (int i=0;i<12;i++) ((int32_t*)ul_ch)[i] = *(int32_t*)ch;
ul_ch+=24;
#else
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip6,
ch,
ul_ch,
8);
#endif
}
else { // this is case without frequency-domain linear interpolation, just take average of LS channel estimates of 4 DMRS REs and use a common value for the whole PRB
LOG_D(PHY,"PUSCH estimation DMRS type 2, no Freq-domain interpolation");
int32_t ch_0, ch_1;
//First PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 4;
ch[1] = ch_1 / 4;
multadd_real_vector_complex_scalar(filt8_avlip0,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip1,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip2,
ch,
ul_ch,
8);
ul_ch -= 24;
for (pilot_cnt=4; pilot_cnt<4*(nb_rb_pusch-1); pilot_cnt += 4) {
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 4;
ch[1] = ch_1 / 4;
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip4,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip5,
ch,
ul_ch,
8);
ul_ch -= 16;
}
// Last PRB
ch_0 = ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 = ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+1) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch_0 += ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15;
ch_1 += ((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15;
pil += 2;
re_offset = (re_offset+5) % gNB->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)];
ch[0] = ch_0 / 4;
ch[1] = ch_1 / 4;
ul_ch[6] += (ch[0] * 1365)>>15; // 1/12*16384
ul_ch[7] += (ch[1] * 1365)>>15; // 1/12*16384
ul_ch += 8;
multadd_real_vector_complex_scalar(filt8_avlip3,
ch,
ul_ch,
8);
ul_ch += 16;
multadd_real_vector_complex_scalar(filt8_avlip6,
ch,
ul_ch,
8);
}
#ifdef DEBUG_PUSCH
ul_ch = (int16_t *)&ul_ch_estimates[p*gNB->frame_parms.nb_antennas_rx+aarx][ch_offset];
for(uint16_t idxP=0; idxP<ceil((float)nb_rb_pusch*12/8); idxP++) {
for(uint8_t idxI=0; idxI<16; idxI += 2) {
printf("%d\t%d\t",ul_ch[idxP*16+idxI],ul_ch[idxP*16+idxI+1]);
}
printf("%d\n",idxP);
}
#endif
// Convert to time domain
+5 -1
View File
@@ -174,7 +174,11 @@ void rx_nr_prach_ru(RU_t *ru,
int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value;
int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
int sample_offset_slot;
if (!(slot%(fp->slots_per_subframe/2)))
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
else
sample_offset_slot = (prachStartSymbol==0?0:prachStartSymbol*(fp->ofdm_symbol_size+fp->nb_prefix_samples));
//to be checked for mu=0;
LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion);
+1 -1
View File
@@ -1439,7 +1439,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
corr_tmp += corr_re*corr_re + corr_im*corr_im;
} // aa loop
}// group loop
LOG_D(PHY,"cw %d, metric %f dB\n",cw,10*log10(corr_tmp));
if (corr_tmp > corr) {
corr = corr_tmp;
cw_ML=cw;
@@ -239,3 +239,24 @@ short filt8_dcll2[8] = {
short filt8_dclh2[8] = {
0,0,0,0,1489,2979,4468,5958};
short filt8_avlip0[8] = {
16384,16384,16384,16384,16384,16384,16384,15019};
short filt8_avlip1[8] = {
13653,12288,10923,9557,8192,6827,5461,4096};
short filt8_avlip2[8] = {
2731,1365,0,0,0,0,0,0};
short filt8_avlip3[8] = {
2731,4096,5461,6827,8192,9557,10923,12288};
short filt8_avlip4[8] = {
13653,15019,16384,15019,13653,12288,10923,9557};
short filt8_avlip5[8] = {
8192,6827,5461,4096,2731,1365,0,0};
short filt8_avlip6[8] = {
13653,15019,16384,16384,16384,16384,16384,16384};
+14 -1
View File
@@ -169,4 +169,17 @@ extern short filt8_dcll2[8];
extern short filt8_dclh2[8];
#endif
extern short filt8_avlip0[8];
extern short filt8_avlip1[8];
extern short filt8_avlip2[8];
extern short filt8_avlip3[8];
extern short filt8_avlip4[8];
extern short filt8_avlip5[8];
extern short filt8_avlip6[8];
#endif
@@ -45,25 +45,23 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
static int max_pos_fil = 0;
static int count_max_pos_ok = 0;
static int first_time = 1;
int temp = 0, i, aa, max_val = 0, max_pos = 0;
int diff;
short Re,Im,ncoef;
int max_val = 0, max_pos = 0;
const int sync_pos = 0;
uint8_t sync_offset = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
ncoef = 32767 - coef;
short ncoef = 32767 - coef;
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
// we only use channel estimates from tx antenna 0 here
for (i = 0; i < frame_parms->nb_prefix_samples; i++) {
temp = 0;
for (int i = 0; i < frame_parms->nb_prefix_samples; i++) {
int temp = 0;
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)];
int Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)];
temp += (Re*Re/2) + (Im*Im/2);
}
@@ -73,6 +71,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
}
}
if (max_pos > frame_parms->ofdm_symbol_size/2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
// filter position to reduce jitter
if (clear == 1)
max_pos_fil = max_pos;
@@ -82,61 +83,58 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
// do not filter to have proactive timing adjustment
//max_pos_fil = max_pos;
diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
int diff = max_pos_fil - sync_pos;
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if (frame_parms->freq_range==nr_FR2)
sync_offset = 2;
else
sync_offset = 0;
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if ( abs(diff) < (SYNCH_HYST+sync_offset) )
ue->rx_offset = 0;
else
ue->rx_offset = diff;
if(count_max_pos_ok > 10 && first_time == 1)
{
first_time = 0;
ue->time_sync_cell = 1;
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else {
ue->UE_mode[0] = PUSCH;
}
}
if(abs(diff)<5)
count_max_pos_ok ++;
else
count_max_pos_ok = 0;
//printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if(count_max_pos_ok > 10 && first_time == 1)
{
first_time = 0;
ue->time_sync_cell = 1;
if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
//mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else {
ue->UE_mode[0] = PUSCH;
}
}
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
if (ue->rx_offset < 0)
ue->rx_offset += frame_parms->samples_per_frame;
if (ue->rx_offset >= frame_parms->samples_per_frame)
ue->rx_offset -= frame_parms->samples_per_frame;
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff = %i, rx_offset (final) = %i : clear = %d, max_pos = %d, max_pos_fil = %d, max_val = %d, sync_pos %d\n",
subframe,
diff,
ue->rx_offset,
clear,
max_pos,
max_pos_fil,
max_val,
sync_pos);
#endif //DEBUG_PHY
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
subframe,
diff,
ue->rx_offset,
clear,
max_pos,
max_pos_fil,
temp,max_val,
(frame_parms->nb_prefix_samples>>3));
#endif //DEBUG_PHY
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
}
File diff suppressed because it is too large Load Diff
+1
View File
@@ -984,6 +984,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
}
}
}
pdcch_vars->nb_search_space = 0;
return(dci_ind->number_of_dcis);
}
@@ -445,8 +445,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//LOG_I(PHY, "avgs Power per SC is %d\n", avgs);
median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx];
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh);
if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) {
nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
@@ -461,8 +459,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
avgs = cmax(avgs, median[aatx*n_rx + aarx]);
}
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
}
pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh);
}
LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
frame%1024,
+5 -1
View File
@@ -102,7 +102,11 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
if (slot % (fp->slots_per_subframe / 2) == 0)
sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1));
else
sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol;
prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot;
//printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start);
@@ -1044,7 +1044,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G);
+12 -11
View File
@@ -215,11 +215,13 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
}
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G)
{
start_meas(&ue->ulsch_encoding_stats);
/////////////////////////parameters and variables declaration/////////////////////////
///////////
@@ -332,6 +334,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_segmentation_stats);
Kb=nr_segmentation(harq_process->b,
harq_process->c,
harq_process->B,
@@ -340,6 +343,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
pz,
&harq_process->F,
harq_process->BG);
stop_meas(&ue->ulsch_segmentation_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
F = harq_process->F;
@@ -374,14 +378,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//for (int i=0;i<68*384;i++)
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
int temp_opp = 0;
if (opp_enabled) {
opp_enabled = 0;
temp_opp = 1;
}
/*printf("output %d %d %d %d %d \n", harq_process->d[0][0], harq_process->d[0][1], harq_process->d[r][2],harq_process->d[0][3], harq_process->d[0][4]);
for (int cnt =0 ; cnt < 66*(*pz); cnt ++){
printf("%d \n", harq_process->d[0][cnt]);
@@ -397,11 +393,13 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_ldpc_encoding_stats);
for(int j = 0; j < (harq_process->C/8 + 1); j++)
{
impp.macro_num = j;
nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp);
}
stop_meas(&ue->ulsch_ldpc_encoding_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT);
@@ -412,8 +410,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
write_output("ulsch_enc_output0.m","enc0",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,4);
#endif
if (temp_opp) opp_enabled = 1;
///////////
///////////////////////////////////////////////////////////////////////////////
LOG_D(PHY,"setting ndi to %d from pusch_data\n", harq_process->pusch_pdu.pusch_data.new_data_indicator);
@@ -449,6 +445,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,harq_process->pusch_pdu.nrOfLayers);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_rate_matching_stats);
nr_rate_matching_ldpc(Ilbrm,
Tbslbrm,
harq_process->BG,
@@ -460,6 +457,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Kr-F-2*(*pz),
harq_process->pusch_pdu.pusch_data.rv_index,
E);
stop_meas(&ue->ulsch_rate_matching_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_OUT);
@@ -481,10 +479,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//start_meas(i_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_IN);
start_meas(&ue->ulsch_interleaving_stats);
nr_interleaving_ldpc(E,
mod_order,
harq_process->e+r_offset,
harq_process->f+r_offset);
stop_meas(&ue->ulsch_interleaving_stats);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INTERLEAVING_LDPC, VCD_FUNCTION_OUT);
//stop_meas(i_stats);
@@ -509,5 +509,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
stop_meas(&ue->ulsch_encoding_stats);
return(0);
}
+3 -2
View File
@@ -159,7 +159,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl);
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G);
///////////
////////////////////////////////////////////////////////////////////
@@ -529,7 +529,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
nr_normal_prefix_mod(txdataF[ap],
&txdata[ap][tx_offset],
14,
frame_parms);
frame_parms,
slot);
}
}
+4
View File
@@ -819,6 +819,8 @@ typedef struct PHY_VARS_gNB_s {
uint32_t max_peak_val;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
/// \brief sinr for all subcarriers of the current link (used only for abstraction).
/// first index: ? [0..N_RB_DL*12[
double *sinr_dB;
@@ -838,6 +840,8 @@ typedef struct PHY_VARS_gNB_s {
int **dl_precoder_SgNB[3];
char log2_maxp; /// holds the maximum channel/precoder coefficient
int prb_interpolation;
/// if ==0 enables phy only test mode
int mac_enabled;
/// counter to average prach energh over first 100 prach opportunities
+4 -1
View File
@@ -868,7 +868,9 @@ typedef struct {
uint32_t perfect_ce;
// flag to activate PRB based averaging of channel estimates
// when off, defaults to frequency domain interpolation
int prb_interpolation;
int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX];
@@ -1005,6 +1007,7 @@ typedef struct {
time_stats_t ofdm_mod_stats;
time_stats_t ulsch_encoding_stats;
time_stats_t ulsch_ldpc_encoding_stats;
time_stats_t ulsch_modulation_stats;
time_stats_t ulsch_segmentation_stats;
time_stats_t ulsch_rate_matching_stats;
+5
View File
@@ -329,6 +329,9 @@ struct NR_DL_FRAME_PARMS {
/// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211
/// First dimension is for the direction of the link (0 DL, 1 UL)
int16_t symbol_rotation[2][224*2];
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
int16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// shift of pilot position in one RB
uint8_t nushift;
/// SRS configuration from TS 38.331 RRC
@@ -362,6 +365,8 @@ struct NR_DL_FRAME_PARMS {
uint8_t ssb_index;
/// PBCH polar encoder params
t_nrPolar_params pbch_polar_params;
/// OFDM symbol offset divisor for UL
uint32_t ofdm_offset_divisor;
};
+2
View File
@@ -119,6 +119,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples,
CYCLIC_PREFIX);
slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size;
slot_offsetF += fp->ofdm_symbol_size;
}
else {
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF],
@@ -128,6 +129,7 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) {
fp->nb_prefix_samples0,
CYCLIC_PREFIX);
slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size;
slot_offsetF += fp->ofdm_symbol_size;
}
}
}
+7 -1
View File
@@ -383,7 +383,13 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
timing_advance_update = sync_pos / bw_scaling;
int sync_pos_rounded;
// do some integer rounding to improve TA accuracy
if (sync_pos > 0)
sync_pos_rounded = sync_pos + (bw_scaling / 2) - 1;
else
sync_pos_rounded = sync_pos - (bw_scaling / 2) - 1;
timing_advance_update = sync_pos_rounded / bw_scaling;
// put timing advance command in 0..63 range
timing_advance_update += 31;
+2 -3
View File
@@ -70,7 +70,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
for (i = 0; i < dl_config->number_pdus; ++i){
AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
AssertFatal(dl_config->dl_config_list[i].pdu_type<=FAPI_NR_DL_CONFIG_TYPES,"pdu_type %d > 2\n",dl_config->dl_config_list[i].pdu_type);
LOG_D(PHY, "In %s: received 1 DL %s PDU of %d total DL PDUs:\n", __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
LOG_D(PHY, "In %s: frame %d slot %d received 1 DL %s PDU of %d total DL PDUs:\n",
__FUNCTION__, scheduled_response->frame, slot, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus);
if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) {
@@ -227,9 +228,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
break;
}
}
memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t));
}
}
return 0;
+1 -1
View File
@@ -252,7 +252,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling;
LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
__FUNCTION__,
ue->Mod_id,
frame_tx,
+10 -10
View File
@@ -413,6 +413,7 @@ int main(int argc, char **argv)
uint16_t rbSize = 106;
uint8_t mcsIndex = 9;
uint8_t dlsch_threads = 0;
int prb_inter = 0;
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
}
@@ -423,7 +424,7 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL;
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) {
while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) {
switch (c) {
case 'f':
scg_fd = fopen(optarg,"r");
@@ -479,14 +480,10 @@ int main(int argc, char **argv)
break;
/*case 'i':
interf1=atoi(optarg);
case 'i':
prb_inter=1;
break;
case 'j':
interf2=atoi(optarg);
break;*/
case 'n':
n_trials = atoi(optarg);
break;
@@ -645,7 +642,7 @@ int main(int argc, char **argv)
printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n");
printf("-y Number of TX antennas used in gNB\n");
printf("-z Number of RX antennas used in UE\n");
//printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n");
printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n");
//printf("-j Relative strength of second intefering gNB (in dB) - cell_id mod 3 = 2\n");
printf("-R N_RB_DL\n");
printf("-O oversampling factor (1,2,4,8,16)\n");
@@ -691,6 +688,7 @@ int main(int argc, char **argv)
memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
gNB->ofdm_offset_divisor = UINT_MAX;
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx;
@@ -911,6 +909,7 @@ int main(int argc, char **argv)
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
UE->if_inst->dl_indication = nr_ue_dl_indication;
UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
UE->prb_interpolation = prb_inter;
UE_mac->if_module = nr_ue_if_module_init(0);
@@ -1084,7 +1083,8 @@ int main(int argc, char **argv)
nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
&txdata[aa][tx_offset],
14,
frame_parms);
frame_parms,
slot);
}
}
@@ -1319,7 +1319,7 @@ int main(int argc, char **argv)
LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
if (UE->frame_parms.nb_antennas_rx>1)
LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1);
LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0][0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1);
write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0);
break;
@@ -321,7 +321,7 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
mac->RA_attempt_number++;
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id){
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+3
View File
@@ -135,7 +135,9 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band);
fp->ofdm_offset_divisor = UINT_MAX;
nr_init_frame_parms(gNB_config, fp);
init_timeshift_rotation(fp);
init_symbol_rotation(fp);
@@ -431,6 +433,7 @@ int main(int argc, char **argv)
RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
gNB->ofdm_offset_divisor = UINT_MAX;
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
frame_parms->nb_antennas_tx = n_tx;
frame_parms->nb_antennas_rx = n_rx;
+1 -1
View File
@@ -504,7 +504,7 @@ int main(int argc, char **argv)
unsigned int G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl);
if (input_fd == NULL) {
nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G);
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G);
}
printf("\n");
+43 -14
View File
@@ -302,6 +302,7 @@ int main(int argc, char **argv)
float effRate;
//float eff_tp_check = 0.7;
uint8_t snrRun;
int prb_inter = 0;
int enable_ptrs = 0;
int modify_dmrs = 0;
@@ -335,7 +336,7 @@ int main(int argc, char **argv)
/* initialize the sin-cos table */
InitSinLUT();
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) {
while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:ikl:m:n:p:r:s:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) {
printf("handling optarg %c\n",c);
switch (c) {
@@ -427,14 +428,10 @@ int main(int argc, char **argv)
break;
/*case 'i':
interf1 = atoi(optarg);
break;
case 'i':
prb_inter=1;
break;
case 'j':
interf2 = atoi(optarg);
break;*/
case 'k':
printf("Setting threequarter_fs_flag\n");
openair0_cfg[0].threequarter_fs= 1;
@@ -465,6 +462,14 @@ int main(int argc, char **argv)
printf("Setting SNR0 to %f\n", snr0);
break;
case 'u':
mu = atoi(optarg);
break;
case 'w':
start_rb = atoi(optarg);
break;
/*
case 't':
eff_tp_check = (float)atoi(optarg)/100;
@@ -586,13 +591,15 @@ int main(int argc, char **argv)
printf("-f Number of frames to simulate\n");
printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n");
printf("-h This message\n");
//printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
printf("-i Activate PRB based averaging for channel estimation. Frequncy domain interpolation by default.\n");
//printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
printf("-s Starting SNR, runs from SNR0 to SNR0 + 10 dB if ending SNR isn't given\n");
printf("-m MCS value\n");
printf("-n Number of trials to simulate\n");
printf("-p Use extended prefix mode\n");
printf("-t Delay spread for multipath channel\n");
printf("-u Set the numerology\n");
printf("-w Start PRB for PUSCH\n");
//printf("-x Transmission mode (1,2,6 for the moment)\n");
printf("-y Number of TX antennas used in eNB\n");
printf("-z Number of RX antennas used in UE\n");
@@ -633,10 +640,12 @@ int main(int argc, char **argv)
if (N_RB_UL >= 217) sampling_frequency = 122.88;
else if (N_RB_UL >= 106) sampling_frequency = 61.44;
else if (N_RB_UL >= 32) sampling_frequency = 32.72;
else { printf("Need at least 106 PRBs\b"); exit(-1); }
if (N_RB_UL == 273) bandwidth = 100;
else if (N_RB_UL == 217) bandwidth = 80;
else if (N_RB_UL == 106) bandwidth = 40;
else if (N_RB_UL == 32) bandwidth = 50;
else { printf("Add N_RB_UL %d\n",N_RB_UL); exit(-1); }
if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
@@ -657,6 +666,7 @@ int main(int argc, char **argv)
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
gNB->ofdm_offset_divisor = UINT_MAX;
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
char tp_param[] = "n";
@@ -669,6 +679,7 @@ int main(int argc, char **argv)
gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t));
gNB->UL_INFO.rx_ind.number_of_pdus = 0;
gNB->UL_INFO.crc_ind.number_crcs = 0;
gNB->prb_interpolation = prb_inter;
frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH)
@@ -801,7 +812,11 @@ int main(int argc, char **argv)
nr_scheduled_response_t scheduled_response;
fapi_nr_ul_config_request_t ul_config;
fapi_nr_tx_request_t tx_req;
memset(&scheduled_response, 0, sizeof(scheduled_response));
memset(&ul_config, 0, sizeof(ul_config));
memset(&tx_req, 0, sizeof(tx_req));
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
uint8_t ptrs_mcs3 = 10;
@@ -949,9 +964,12 @@ int main(int argc, char **argv)
input_fd);
if (read_errors==0) exit(1);
for (int i=0;i<16;i+=2) printf("slot_offset %d : %d,%d\n",
slot_offset,
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
slot_offset,
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i],
((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]);
mod_order = nr_get_Qm_ul(Imcs, mcs_table);
code_rate = nr_get_code_rate_ul(Imcs, mcs_table);
}
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
@@ -973,6 +991,10 @@ int main(int argc, char **argv)
reset_meas(&gNB->ulsch_llr_stats);
reset_meas(&gNB->ulsch_channel_compensation_stats);
reset_meas(&gNB->ulsch_rbs_extraction_stats);
reset_meas(&UE->ulsch_ldpc_encoding_stats);
reset_meas(&UE->ulsch_rate_matching_stats);
reset_meas(&UE->ulsch_interleaving_stats);
reset_meas(&UE->ulsch_encoding_stats);
clear_pusch_stats(gNB);
for (trial = 0; trial < n_trials; trial++) {
@@ -1165,7 +1187,7 @@ int main(int argc, char **argv)
frame_parms->ofdm_symbol_size/(12*nb_rb));
for (i=0; i<slot_length; i++) {
for (int aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
for (int aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
s_re[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)]);
s_im[aa][i] = ((double)(((short *)&UE->common_vars.txdata[aa][slot_offset]))[(i<<1)+1]);
}
@@ -1233,6 +1255,8 @@ int main(int argc, char **argv)
&gNB->pusch_vars[0]->rxdataF_ext[0][start_symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
LOG_M("chestF0.m","chF0",
&gNB->pusch_vars[0]->ul_ch_estimates[0][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
LOG_M("chestT0.m","chT0",
&gNB->pusch_vars[0]->ul_ch_estimates_time[0][0],frame_parms->ofdm_symbol_size,1,1);
LOG_M("chestF0_ext.m","chF0_ext",
&gNB->pusch_vars[0]->ul_ch_estimates_ext[0][(start_symbol+1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
(nb_symb_sch-1)*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
@@ -1350,6 +1374,11 @@ int main(int argc, char **argv)
printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation");
printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling");
printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time");
printStatIndent(&UE->ulsch_encoding_stats,"ULSCH total encoding time");
printStatIndent2(&UE->ulsch_segmentation_stats,"ULSCH segmentation time");
printStatIndent2(&UE->ulsch_ldpc_encoding_stats,"ULSCH LDPC encoder time");
printStatIndent2(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time");
printStatIndent2(&UE->ulsch_interleaving_stats,"ULSCH interleaving time");
//printStatIndent2(&gNB->ulsch_deinterleaving_stats,"ULSCH deinterleaving");
//printStatIndent2(&gNB->ulsch_rate_unmatching_stats,"ULSCH rate matching rx");
//printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
+7 -4
View File
@@ -47,6 +47,7 @@
#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd"
#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference"
#define CONFIG_STRING_L1_PUSCH_PROC_THREADS "pusch_proc_threads"
#define CONFIG_STRING_L1_OFDM_OFFSET_DIVISOR "ofdm_offset_divisor"
#define CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD "pucch0_dtx_threshold"
#define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD "prach_dtx_threshold"
#define CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD "pusch_dtx_threshold"
@@ -64,7 +65,8 @@
{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_OFDM_OFFSET_DIVISOR, NULL, 0, uptr:NULL, defuintval:8, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0} \
@@ -79,9 +81,10 @@
#define L1_LOCAL_N_PORTD_IDX 7
#define L1_REMOTE_N_PORTD_IDX 8
#define L1_PUSCH_PROC_THREADS 9
#define L1_PUCCH0_DTX_THRESHOLD 10
#define L1_PRACH_DTX_THRESHOLD 11
#define L1_PUSCH_DTX_THRESHOLD 12
#define L1_OFDM_OFFSET_DIVISOR 10
#define L1_PUCCH0_DTX_THRESHOLD 11
#define L1_PRACH_DTX_THRESHOLD 12
#define L1_PUSCH_DTX_THRESHOLD 13
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
#endif
+1
View File
@@ -573,6 +573,7 @@ void RCconfig_NR_L1(void) {
}
RC.gNB[j]->pusch_proc_threads = *(L1_ParamList.paramarray[j][L1_PUSCH_PROC_THREADS].uptr);
RC.gNB[j]->ofdm_offset_divisor = *(L1_ParamList.paramarray[j][L1_OFDM_OFFSET_DIVISOR].uptr);
RC.gNB[j]->pucch0_thres = *(L1_ParamList.paramarray[j][L1_PUCCH0_DTX_THRESHOLD].uptr);
RC.gNB[j]->prach_thres = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD].uptr);
RC.gNB[j]->pusch_thres = *(L1_ParamList.paramarray[j][L1_PUSCH_DTX_THRESHOLD].uptr);
+2 -2
View File
@@ -292,8 +292,8 @@ typedef struct {
/// Random-access Contention Resolution Timer active flag
uint8_t RA_contention_resolution_timer_active;
/// Random-access Contention Resolution Timer count value
uint8_t RA_contention_resolution_cnt;
int RA_contention_resolution_target_frame;
int RA_contention_resolution_target_slot;
/// Transmitted UE Contention Resolution Identifier
uint8_t cont_res_id[6];
+1 -1
View File
@@ -363,7 +363,7 @@ void nr_get_prach_resources(module_id_t mod_id,
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
void nr_ue_msg2_scheduler(module_id_t mod_id, uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot);
+24 -21
View File
@@ -492,18 +492,27 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
ra->RA_attempt_number++;
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc) ?
RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc) ?
mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup:
mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
RA_config_t *ra = &mac->ra;
long mu = (mac->scc) ?
mac->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing :
mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
int subframes_per_slot = nr_slots_per_frame[mu]/10;
LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP);
// start contention resolution timer (cnt in slots)
int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1)<<3;
ra->RA_contention_resolution_target_frame = frameP + (RA_contention_resolution_timer_subframes/10);
ra->RA_contention_resolution_target_slot = (slotP + (RA_contention_resolution_timer_subframes * subframes_per_slot)) % nr_slots_per_frame[mu];
LOG_D(MAC,"In %s: [UE %d] CB-RA: contention resolution timer set in frame.slot %d.%d and expiring in %d.%d\n",
__FUNCTION__, mod_id, frameP, slotP, ra->RA_contention_resolution_target_frame, ra->RA_contention_resolution_target_slot);
// start contention resolution timer
ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8;
ra->RA_contention_resolution_timer_active = 1;
ra->ra_state = WAIT_CONTENTION_RESOLUTION;
@@ -774,20 +783,15 @@ void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame
RA_config_t *ra = &mac->ra;
if (ra->RA_contention_resolution_timer_active == 1) {
ra->RA_contention_resolution_cnt--;
LOG_D(MAC, "In %s: [%d.%d] RA contention resolution timer %d\n", __FUNCTION__, frame, slot, ra->RA_contention_resolution_cnt);
if (ra->RA_contention_resolution_cnt == 0) {
ra->t_crnti = 0;
ra->RA_active = 0;
ra->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id);
nr_ra_failed(module_id, cc_id, prach_resources, frame, slot);
}
if (frame >= ra->RA_contention_resolution_target_frame &&
slot >= ra->RA_contention_resolution_target_slot) {
ra->t_crnti = 0;
ra->RA_active = 0;
ra->RA_contention_resolution_timer_active = 0;
// Signal PHY to quit RA procedure
LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id);
nr_ra_failed(module_id, cc_id, prach_resources, frame, slot);
}
}
}
@@ -810,7 +814,6 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
ra->RA_contention_resolution_cnt = -1;
ra->RA_contention_resolution_timer_active = 0;
mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
@@ -182,7 +182,8 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
rel15->dci_length_options[0] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_TC, rel15->BWPSize, bwp_id);
for (int i = 0; i < rel15->num_dci_options; i++)
rel15->dci_length_options[i] = nr_dci_size(initialUplinkBWP, mac->cg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_TC, rel15->BWPSize, bwp_id);
break;
case NR_RNTI_SP_CSI:
break;
+63 -31
View File
@@ -171,7 +171,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
uint16_t ssb_start_subcarrier,
uint16_t cell_id)
{
LOG_D(MAC,"[L2][MAC] decode mib\n");
LOG_I(MAC,"[L2][MAC] decode mib\n");
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
mac->physCellId = cell_id;
@@ -505,7 +505,10 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15);
if ((ret&1) == 1) return -1;
else if (ret == 2) dci->dci_format = NR_UL_DCI_FORMAT_0_0;
else if (ret == 2) {
dci->dci_format = NR_UL_DCI_FORMAT_0_0;
def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
}
return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci));
}
@@ -2493,9 +2496,10 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
//switch to DCI_0_0
if (dci_pdu_rel15->format_indicator == 0)
if (dci_pdu_rel15->format_indicator == 0) {
dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0];
return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15);
}
#ifdef DEBUG_EXTRACT_DCI
LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu);
#endif
@@ -2691,6 +2695,12 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
//switch to DCI_0_0
if (dci_pdu_rel15->format_indicator == 0) {
dci_pdu_rel15 = &mac->def_dci_pdu_rel15[NR_UL_DCI_FORMAT_0_0];
return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, dci_pdu, dci_pdu_rel15);
}
if (dci_pdu_rel15->format_indicator == 0)
return 1; // discard dci, format indicator not corresponding to dci_format
@@ -2829,40 +2839,62 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
break;
case NR_RNTI_TC:
/*
// indicating a DL DCI format 1bit
dci_pdu->= (*dci_pdu>>(dci_size-pos)format_indicator&1)<<(dci_size-pos++);
// Freq domain assignment max 16 bit
//Identifier for DCI formats
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu);
#endif
if (dci_pdu_rel15->format_indicator == 1)
return 1; // discard dci, format indicator not corresponding to dci_format
fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
for (int i=0; i<fsize; i++)
dci_pdu->= ((*dci_pdu>>(dci_size-pos)frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++);
pos+=fsize;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"Freq domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu);
#endif
// Time domain assignment 4bit
for (int i=0; i<4; i++)
dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)time_domain_assignment>>(3-i))&1)<<(dci_size-pos++);
pos+=4;
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu);
#endif
// Frequency hopping flag  E1 bit
dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)frequency_hopping_flag&1)<<(dci_size-pos++);
pos++;
dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"frequency_hopping %d (1 bit)=> %d (0x%lx)\n",dci_pdu_rel15->frequency_hopping_flag.val,dci_size-pos,*dci_pdu);
#endif
// MCS 5 bit
for (int i=0; i<5; i++)
dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)mcs>>(4-i))&1)<<(dci_size-pos++);
pos+=5;
dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu);
#endif
// New data indicator 1bit
dci_pdu->= ((uint64_t)*dci_pdu>>(dci_size-pos)ndi&1)<<(dci_size-pos++);
pos++;
dci_pdu_rel15->ndi= (*dci_pdu>>(dci_size-pos))&1;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu);
#endif
// Redundancy version 2bit
for (int i=0; i<2; i++)
dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)rv>>(1-i))&1)<<(dci_size-pos++);
pos+=2;
dci_pdu_rel15->rv= (*dci_pdu>>(dci_size-pos))&3;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu);
#endif
// HARQ process number 4bit
for (int i=0; i<4; i++)
*dci_pdu |= (((uint64_t)*dci_pdu>>(dci_size-pos)harq_pid>>(3-i))&1)<<(dci_size-pos++);
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu);
#endif
// TPC command for scheduled PUSCH  E2 bits
for (int i=0; i<2; i++)
dci_pdu->= (((uint64_t)*dci_pdu>>(dci_size-pos)tpc>>(1-i))&1)<<(dci_size-pos++);
*/
// UL/SUL indicator  E1 bit
/*
commented for now (RK): need to get this information from BWP descriptor
if (cfg->pucch_config.pucch_GroupHopping.value)
dci_pdu->= ((uint64_t)dci_pdu_rel15->ul_sul_indicator&1)<<(dci_size-pos++);
*/
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3;
#ifdef DEBUG_EXTRACT_DCI
LOG_I(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu);
#endif
break;
}
@@ -3278,7 +3310,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
#endif
*/
LOG_I(MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
LOG_D(MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
break;
case DL_SCH_LCID_CON_RES_ID:
+9 -5
View File
@@ -879,7 +879,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
nr_dcireq_t dcireq;
if(mac->cg != NULL){ // we have a cg
dcireq.module_id = mod_id;
dcireq.gNB_index = gNB_index;
dcireq.cc_id = cc_id;
@@ -896,8 +895,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
// this is for Msg2/Msg4
if (mac->ra.ra_state >= WAIT_RAR) {
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
rel15->num_dci_options = 1;
rel15->num_dci_options = mac->ra.ra_state == WAIT_RAR ? 1 : 2;
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
if (mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION)
rel15->dci_format_options[1] = NR_UL_DCI_FORMAT_0_0; // msg3 retransmission
config_dci_pdu(mac, rel15, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC , -1);
fill_dci_search_candidates(mac->ra.ss, rel15);
dl_config->number_pdus = 1;
@@ -979,11 +980,15 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
tx_req.tx_request_body[0].pdu_index = j;
tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
if (ra->ra_state == WAIT_CONTENTION_RESOLUTION && !ra->cfra){
LOG_I(NR_MAC,"[RAPROC] RA-Msg3 retransmitted\n");
// 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 transmission
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
}
if (ra->ra_state == WAIT_RAR && !ra->cfra){
LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n");
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index);
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index);
}
}
}
@@ -1015,7 +1020,6 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
int delta = 0;
NR_BWP_Uplink_t *ubwp = mac->ULbwp[0];
// Get the numerology to calculate the Tx frame and slot
int mu = ubwp ?
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
+335 -115
View File
@@ -653,33 +653,228 @@ void nr_initiate_ra_proc(module_id_t module_idP,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
{
gNB_MAC_INST *mac = RC.nrmac[module_idP];
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
start_meas(&mac->schedule_ra);
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_RA_t *ra = &cc->ra[i];
LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
switch (ra->state) {
case Msg2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
break;
case Msg4:
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
break;
case WAIT_Msg4_ACK:
nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
break;
default:
break;
}
gNB_MAC_INST *mac = RC.nrmac[module_idP];
start_meas(&mac->schedule_ra);
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
NR_RA_t *ra = &cc->ra[i];
LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
switch (ra->state) {
case Msg2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
break;
case Msg3_retransmission:
nr_generate_Msg3_retransmission(module_idP, CC_id, frameP, slotP, ra);
break;
case Msg4:
nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
break;
case WAIT_Msg4_ACK:
nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
break;
default:
break;
}
}
stop_meas(&mac->schedule_ra);
}
stop_meas(&mac->schedule_ra);
}
void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
NR_BWP_Uplink_t *ubwp = ra->CellGroup ?
ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1] :
NULL;
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ?
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
int mu = ubwp ?
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
uint8_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]);
const int sched_slot = (slot + K2) % nr_slots_per_frame[mu];
if (is_xlsch_in_slot(RC.nrmac[module_idP]->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) {
// beam association for FR2
int16_t *tdd_beam_association = nr_mac->tdd_beam_association;
if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) {
uint8_t tdd_period_slot = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0))
tdd_period_slot++;
int num_tdd_period = sched_slot/tdd_period_slot;
if((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=ra->beam_id))
return; // can't schedule retransmission in this slot
else
tdd_beam_association[num_tdd_period] = ra->beam_id;
}
int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
int fh = 0;
int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
if (ra->CellGroup) {
AssertFatal(ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength;
mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType;
scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0;
if ((bwpStart < act_bwp_start) || (bwpSize > act_bwp_size))
bwpStart = act_bwp_start;
}
uint16_t *vrb_map_UL =
&RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
int rbStart = 0;
for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (bwpSize - ra->msg3_nb_rb)); i++) {
if (vrb_map_UL[rbStart + bwpStart + i]) {
rbStart += i;
i = 0;
}
}
if (rbStart > (bwpSize - ra->msg3_nb_rb)) {
// cannot find free vrb_map for msg3 retransmission in this slot
return;
}
LOG_I(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d Scheduling retransmission of Msg3 in (%d,%d)\n",
module_idP, frame, slot, CC_id, sched_frame, sched_slot);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][sched_slot];
AssertFatal(future_ul_tti_req->SFN == sched_frame
&& future_ul_tti_req->Slot == sched_slot,
"future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
future_ul_tti_req->SFN,
future_ul_tti_req->Slot,
sched_frame,
sched_slot);
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
fill_msg3_pusch_pdu(pusch_pdu, scc,
ra->msg3_round,
startSymbolAndLength,
ra->rnti, scs,
bwpSize, bwpStart,
mappingtype, fh,
rbStart, ra->msg3_nb_rb);
future_ul_tti_req->n_pdus += 1;
// generation of DCI 0_0 to schedule msg3 retransmission
NR_SearchSpace_t *ss = ra->ra_ss;
NR_BWP_Downlink_t *bwp = NULL;
NR_ControlResourceSet_t *coreset = NULL;
NR_BWP_t *genericParameters = NULL;
if (ra->CellGroup &&
ra->CellGroup->spCellConfig &&
ra->CellGroup->spCellConfig->spCellConfigDedicated &&
ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList &&
ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]) {
bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
genericParameters = &bwp->bwp_Common->genericParameters;
}
else {
genericParameters= &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
}
if (*ss->controlResourceSetId == 0)
coreset = nr_mac->sched_ctrlCommon->coreset; // this is coreset 0
else
coreset = get_coreset(scc, bwp, ss, NR_SearchSpace__searchSpaceType_PR_common);
AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg3 retransmission\n");
nfapi_nr_ul_dci_request_t *ul_dci_req = &nr_mac->UL_dci_req[CC_id];
const int coresetid = coreset->controlResourceSetId;
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid];
if (!pdcch_pdu_rel15) {
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
ul_dci_req->numPdus += 1;
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, genericParameters, NULL);
nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
}
uint8_t aggregation_level;
uint8_t nr_of_candidates;
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level, 0, 0, nr_of_candidates);
if (CCEIndex < 0) {
LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
return;
}
// Fill PDCCH DL DCI PDU
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
pdcch_pdu_rel15->numDlDci++;
dci_pdu->RNTI = ra->rnti;
dci_pdu->ScramblingId = *scc->physCellId;
dci_pdu->ScramblingRNTI = 0;
dci_pdu->AggregationLevel = aggregation_level;
dci_pdu->CceIndex = CCEIndex;
dci_pdu->beta_PDCCH_1_0 = 0;
dci_pdu->powerControlOffsetSS = 1;
dci_pdu_rel15_t uldci_payload;
memset(&uldci_payload, 0, sizeof(uldci_payload));
config_uldci(ubwp,
scc,
pusch_pdu,
&uldci_payload,
NR_UL_DCI_FORMAT_0_0,
ra->Msg3_tda_id,
ra->msg3_TPC,
0, // not used in format 0_0
ra->bwp_id);
fill_dci_pdu_rel15(scc,
ra->CellGroup,
dci_pdu,
&uldci_payload,
NR_UL_DCI_FORMAT_0_0,
NR_RNTI_TC,
pusch_pdu->bwp_size,
ra->bwp_id);
// Mark the corresponding RBs as used
for (int rb = 0; rb < ra->msg3_nb_rb; rb++) {
vrb_map_UL[rbStart + bwpStart + rb] = 1;
}
// reset state to wait msg3
ra->state = WAIT_Msg3;
ra->Msg3_frame = sched_frame;
ra->Msg3_slot = sched_slot;
}
}
void nr_get_Msg3alloc(module_id_t module_id,
int CC_id,
@@ -690,45 +885,45 @@ void nr_get_Msg3alloc(module_id_t module_id,
NR_RA_t *ra,
int16_t *tdd_beam_association) {
// msg3 is schedulend in mixed slot in the following TDD period
// msg3 is scheduled in mixed slot in the following TDD period
uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
int mu = ubwp ?
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
int StartSymbolIndex = 0;
int NrOfSymbols = 0;
int startSymbolAndLength = 0;
int temp_slot = 0;
ra->Msg3_tda_id = 16; // initialization to a value above limit
int mu = ubwp ?
ubwp->bwp_Common->genericParameters.subcarrierSpacing :
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
int StartSymbolIndex = 0;
int NrOfSymbols = 0;
int startSymbolAndLength = 0;
int temp_slot = 0;
ra->Msg3_tda_id = 16; // initialization to a value above limit
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ?
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ?
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList:
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
uint8_t k2 = 0;
for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) {
startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
// we want to transmit in the uplink symbols of mixed slot
if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2;
temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) {
ra->Msg3_tda_id = i;
break;
}
uint8_t k2 = 0;
for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) {
startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
// we want to transmit in the uplink symbols of mixed slot
if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2;
temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) {
ra->Msg3_tda_id = i;
break;
}
}
}
AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
if (nr_slots_per_frame[mu]>temp_slot)
ra->Msg3_frame = current_frame;
else
ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024;
if (nr_slots_per_frame[mu]>temp_slot)
ra->Msg3_frame = current_frame;
else
ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024;
// beam association for FR2
if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) {
@@ -750,7 +945,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,
MAX_BWP_SIZE);
/* search msg3_nb_rb free RBs */
/* search msg3_nb_rb free RBs */
int rbSize = 0;
int rbStart = 0;
while (rbSize < msg3_nb_rb) {
@@ -768,6 +963,75 @@ void nr_get_Msg3alloc(module_id_t module_id,
ra->msg3_first_rb = rbStart;
}
void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_ServingCellConfigCommon_t *scc,
int round,
int startSymbolAndLength,
rnti_t rnti, int scs,
int bwp_size, int bwp_start,
int mappingtype, int fh,
int msg3_first_rb, int msg3_nb_rb) {
int start_symbol_index,nr_of_symbols;
SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = rnti;
pusch_pdu->handle = 0;
pusch_pdu->bwp_start = bwp_start;
pusch_pdu->bwp_size = bwp_size;
pusch_pdu->subcarrier_spacing = scs;
pusch_pdu->cyclic_prefix = 0;
pusch_pdu->mcs_index = 0;
pusch_pdu->mcs_table = 0;
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_pdu->transform_precoding = 1;
else
pusch_pdu->transform_precoding = 0;
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position);
LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
pusch_pdu->dmrs_config_type = 0;
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
pusch_pdu->resource_alloc = 1; //type 1
pusch_pdu->rb_start = msg3_first_rb;
if (msg3_nb_rb > pusch_pdu->bwp_size)
AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
else
pusch_pdu->rb_size = msg3_nb_rb;
pusch_pdu->vrb_to_prb_mapping = 0;
pusch_pdu->frequency_hopping = fh;
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
//Resource Allocation in time domain
pusch_pdu->start_symbol_index = start_symbol_index;
pusch_pdu->nr_of_symbols = nr_of_symbols;
//Optional Data only included if indicated in pduBitmap
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round];
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 1;
pusch_pdu->pusch_data.num_cb = 0;
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
12, // nb dmrs set for no data in dmrs symbol
0, //nb_rb_oh
0, // to verify tb scaling
pusch_pdu->nrOfLayers)>>3;
}
void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu)
{
gNB_MAC_INST *mac = RC.nrmac[module_idP];
@@ -790,7 +1054,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
vrb_map_UL[i + ra->msg3_first_rb] = 1;
}
LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Slot %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot];
AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame
@@ -804,7 +1068,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
future_ul_tti_req->n_pdus += 1;
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int abwp_size = ibwp_size;
@@ -837,67 +1101,20 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
ra->msg3_round,
ra->rnti);
int start_symbol_index,nr_of_symbols;
SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols);
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
pusch_pdu->rnti = ra->rnti;
pusch_pdu->handle = 0;
int bwp_start;
if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
pusch_pdu->bwp_start = abwp_start;
bwp_start = abwp_start;
else
pusch_pdu->bwp_start = ibwp_start;
pusch_pdu->bwp_size = ibwp_size;
pusch_pdu->subcarrier_spacing = scs;
pusch_pdu->cyclic_prefix = 0;
pusch_pdu->mcs_index = 0;
pusch_pdu->mcs_table = 0;
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
pusch_pdu->transform_precoding = 1;
else
pusch_pdu->transform_precoding = 0;
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
bwp_start = ibwp_start;
pusch_pdu->ul_dmrs_symb_pos = get_l_prime(nr_of_symbols,mappingtype,pusch_dmrs_pos2,pusch_len1,start_symbol_index, scc->dmrs_TypeA_Position);
LOG_D(MAC, "MSG3 start_sym:%d NR Symb:%d mappingtype:%d , ul_dmrs_symb_pos:%x\n", start_symbol_index, nr_of_symbols, mappingtype, pusch_pdu->ul_dmrs_symb_pos);
pusch_pdu->dmrs_config_type = 0;
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id.
pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0.
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
pusch_pdu->resource_alloc = 1; //type 1
//pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
pusch_pdu->rb_start = ra->msg3_first_rb;
if (ra->msg3_nb_rb > pusch_pdu->bwp_size)
AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
else
pusch_pdu->rb_size = ra->msg3_nb_rb;
pusch_pdu->vrb_to_prb_mapping = 0;
pusch_pdu->frequency_hopping = fh;
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
pusch_pdu->uplink_frequency_shift_7p5khz = 0;
//Resource Allocation in time domain
pusch_pdu->start_symbol_index = start_symbol_index;
pusch_pdu->nr_of_symbols = nr_of_symbols;
//Optional Data only included if indicated in pduBitmap
pusch_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213
pusch_pdu->pusch_data.harq_process_id = 0;
pusch_pdu->pusch_data.new_data_indicator = 1; // new data
pusch_pdu->pusch_data.num_cb = 0;
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
pusch_pdu->target_code_rate,
pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
12, // nb dmrs set for no data in dmrs symbol
0, //nb_rb_oh
0, // to verify tb scaling
pusch_pdu->nrOfLayers = 1)>>3;
fill_msg3_pusch_pdu(pusch_pdu,scc,
ra->msg3_round,
startSymbolAndLength,
ra->rnti, scs,
ibwp_size, bwp_start,
mappingtype, fh,
ra->msg3_first_rb, ra->msg3_nb_rb);
future_ul_tti_req->n_pdus += 1;
// calling function to fill rar message
nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
@@ -1479,6 +1696,9 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
}
}
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->tb, harq->tb_size));
// DL TX request
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size);
@@ -604,6 +604,7 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp,
uint8_t tpc,
int n_ubwp,
int bwp_id) {
const int bw = NRRIV2BW(ubwp ?
ubwp->bwp_Common->genericParameters.locationAndBandwidth :
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
@@ -1395,41 +1396,53 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
break;
case NFAPI_NR_RNTI_TC:
// indicating a DL DCI format 1bit
*dci_pdu |= (dci_pdu_rel15->format_indicator & 1) << (dci_size - pos++);
// indicating a UL DCI format 1bit
pos=1;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos);
// Freq domain assignment max 16 bit
fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
for (int i = 0; i < fsize; i++)
*dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val >> (fsize - i - 1)) & 1) << (dci_size - pos++);
pos+=fsize;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos);
// Time domain assignment 4bit
for (int i = 0; i < 4; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val >> (3 - i)) & 1) << (dci_size - pos++);
pos += 4;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val & ((1 << 4) - 1)) << (dci_size - pos);
// Frequency hopping flag – 1 bit
*dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 1) << (dci_size - pos++);
pos++;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 1) << (dci_size - pos);
// MCS 5 bit
for (int i = 0; i < 5; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs >> (4 - i)) & 1) << (dci_size - pos++);
pos+=5;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos);
// New data indicator 1bit
*dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos++);
pos++;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos);
// Redundancy version 2bit
for (int i = 0; i < 2; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->rv >> (1 - i)) & 1) << (dci_size - pos++);
pos+=2;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->rv & 0x3) << (dci_size - pos);
// HARQ process number 4bit
for (int i = 0; i < 4; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->harq_pid >> (3 - i)) & 1) << (dci_size - pos++);
// TPC command for scheduled PUSCH – 2 bits
for (int i = 0; i < 2; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc >> (1 - i)) & 1) << (dci_size - pos++);
pos+=4;
*dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos);
// Padding bits
for (int a = pos; a < 32; a++)
*dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++);
// UL/SUL indicator – 1 bit
/*
commented for now (RK): need to get this information from BWP descriptor
if (cfg->pucch_config.pucch_GroupHopping.value)
/* commented for now (RK): need to get this from BWP descriptor
if (cfg->pucch_config.pucch_GroupHopping.value)
*dci_pdu |=
((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&1)<<(dci_size-pos++);
((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&1)<<(dci_size-pos++);
*/
LOG_D(NR_MAC,"N_RB = %i\n", N_RB);
LOG_D(NR_MAC,"dci_size = %i\n", dci_size);
LOG_D(NR_MAC,"fsize = %i\n", fsize);
LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
LOG_D(NR_MAC,"dci_pdu_rel15->frequency_hopping_flag.val = %i\n", dci_pdu_rel15->frequency_hopping_flag.val);
LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
LOG_D(NR_MAC,"dci_pdu_rel15->ndi = %i\n", dci_pdu_rel15->ndi);
LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid);
LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
LOG_D(NR_MAC,"dci_pdu_rel15->padding = %i\n", dci_pdu_rel15->padding);
break;
}
break;
@@ -526,19 +526,26 @@ void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid)
sched_ctrl->sched_ul_bytes = 0;
}
void handle_nr_ul_harq(module_id_t mod_id,
void handle_nr_ul_harq(const int CC_idP,
module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu)
{
gNB_MAC_INST *gNB_mac = RC.nrmac[mod_id];
int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti);
if (UE_id < 0) {
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
if (ra->state >= WAIT_Msg3 &&
ra->rnti == crc_pdu->rnti)
return;
}
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti);
return;
}
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
LOG_W(NR_MAC,
@@ -601,6 +608,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const uint16_t timing_advance,
const uint8_t ul_cqi,
const uint16_t rssi){
gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP];
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
@@ -799,9 +807,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (ra->state != WAIT_Msg3)
continue;
LOG_W(NR_MAC, "Random Access %i failed at state %i (state is not WAIT_Msg3)\n", i, ra->state);
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
if( (frameP!=ra->Msg3_frame) || (slotP!=ra->Msg3_slot))
continue;
if (ra->msg3_round >= MAX_HARQ_ROUNDS - 1) {
LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state);
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
return;
}
LOG_W(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i);
ra->msg3_round++;
ra->state = Msg3_retransmission;
}
}
}
+13 -1
View File
@@ -126,6 +126,8 @@ void nr_get_Msg3alloc(module_id_t module_id,
NR_RA_t *ra,
int16_t *tdd_beam_association);
void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
/* \brief Function in gNB to fill RAR pdu when requested by PHY.
@param ra Instance of RA resources of gNB
@param dlsch_buffer Pointer to RAR input buffer
@@ -136,6 +138,15 @@ void nr_fill_rar(uint8_t Mod_idP,
uint8_t * dlsch_buffer,
nfapi_nr_pusch_pdu_t *pusch_pdu);
void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_ServingCellConfigCommon_t *scc,
int round,
int startSymbolAndLength,
rnti_t rnti, int scs,
int bwp_size, int bwp_start,
int mappingtype, int fh,
int msg3_first_rb, int msg3_nb_rb);
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
@@ -391,7 +402,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const uint8_t ul_cqi,
const uint16_t rssi);
void handle_nr_ul_harq(module_id_t mod_id,
void handle_nr_ul_harq(const int CC_idP,
module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu);
+3 -2
View File
@@ -93,8 +93,9 @@ typedef enum {
RA_IDLE = 0,
Msg2 = 1,
WAIT_Msg3 = 2,
Msg4 = 3,
WAIT_Msg4_ACK = 4
Msg3_retransmission = 3,
Msg4 = 4,
WAIT_Msg4_ACK = 5
} RA_gNB_state_t;
typedef struct NR_preamble_ue {
+1 -1
View File
@@ -182,7 +182,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info)
rx->timing_advance,
rx->ul_cqi,
rx->rssi);
handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc);
handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc);
break;
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
@@ -234,8 +234,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -218,8 +218,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -216,8 +216,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -235,6 +235,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -231,8 +231,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -269,6 +269,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -215,8 +215,10 @@ MACRLCs = (
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -218,6 +218,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -230,11 +230,12 @@ MACRLCs = (
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
}
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
@@ -214,11 +214,12 @@ MACRLCs = (
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
}
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -219,6 +219,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -214,11 +214,12 @@ MACRLCs = (
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
}
{
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
RUs = (
@@ -235,6 +235,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -251,6 +251,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -241,6 +241,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);
@@ -241,6 +241,7 @@ L1s = (
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0
}
);