Merge remote-tracking branch 'origin/develop' into ldpc-decoder-codegen
This commit is contained in:
@@ -47,14 +47,18 @@
|
||||
#include "openair1/SIMULATION/RF/rf.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
|
||||
|
||||
//#define DEBUG_NR_DLSCHSIM
|
||||
|
||||
THREAD_STRUCT thread_struct;
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
UE_nr_rxtx_proc_t proc;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
//uint8_t nfapi_mode = 0;
|
||||
@@ -119,6 +123,7 @@ int main(int argc, char **argv)
|
||||
double DS_TDL = .03;
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
char gNBthreads[128]="n";
|
||||
int Tbslbrm = 950984;
|
||||
|
||||
if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
|
||||
exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n");
|
||||
@@ -426,13 +431,10 @@ int main(int argc, char **argv)
|
||||
NR_gNB_DLSCH_t *dlsch = msgDataTx.dlsch[0][0];
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
|
||||
//time_stats_t *rm_stats, *te_stats, *i_stats;
|
||||
uint8_t is_crnti = 0, llr8_flag = 0;
|
||||
uint8_t is_crnti = 0;
|
||||
unsigned int TBS = 8424;
|
||||
unsigned int available_bits;
|
||||
uint8_t nb_re_dmrs = 6; // No data in dmrs symbol
|
||||
uint16_t length_dmrs = 1;
|
||||
unsigned char mod_order;
|
||||
uint16_t rate;
|
||||
uint8_t Nl = 1;
|
||||
uint8_t rvidx = 0;
|
||||
dlsch->rnti = 1;
|
||||
@@ -440,9 +442,9 @@ int main(int argc, char **argv)
|
||||
dlsch->harq_processes[0]->rvidx = rvidx;*/
|
||||
//printf("dlschsim harqid %d nb_rb %d, mscs %d\n",dlsch->harq_ids[subframe],
|
||||
// dlsch->harq_processes[0]->nb_rb,dlsch->harq_processes[0]->mcs,dlsch->harq_processes[0]->Nl);
|
||||
mod_order = nr_get_Qm_dl(Imcs, mcs_table);
|
||||
rate = nr_get_code_rate_dl(Imcs, mcs_table);
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
|
||||
unsigned char mod_order = nr_get_Qm_dl(Imcs, mcs_table);
|
||||
uint16_t rate = nr_get_code_rate_dl(Imcs, mcs_table);
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
|
||||
TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
|
||||
printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
|
||||
//dlsch->harq_ids[subframe]= 0;
|
||||
@@ -457,6 +459,7 @@ int main(int argc, char **argv)
|
||||
rel15->dlDmrsSymbPos = 4;
|
||||
rel15->mcsIndex[0] = Imcs;
|
||||
rel15->numDmrsCdmGrpsNoData = 1;
|
||||
rel15->maintenance_parms_v3.tbSizeLbrmBytes = Tbslbrm;
|
||||
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
|
||||
short channel_output_fixed[16 * 68 * 384];
|
||||
//unsigned char *estimated_output;
|
||||
@@ -473,9 +476,11 @@ int main(int argc, char **argv)
|
||||
harq_process->Qm = mod_order;
|
||||
harq_process->rvidx = rvidx;
|
||||
harq_process->R = rate;
|
||||
harq_process->TBS = TBS;
|
||||
harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
|
||||
harq_process->dlDmrsSymbPos = 4;
|
||||
harq_process->n_dmrs_cdm_groups = 1;
|
||||
harq_process->tbslbrm = Tbslbrm;
|
||||
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
|
||||
|
||||
unsigned char *test_input=dlsch->harq_process.pdu;
|
||||
@@ -492,8 +497,8 @@ int main(int argc, char **argv)
|
||||
|
||||
//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
|
||||
// generate signal
|
||||
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
|
||||
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
|
||||
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||
if (input_fd == NULL) {
|
||||
nr_dlsch_encoding(gNB, frame, slot, &dlsch->harq_process, frame_parms,output,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
}
|
||||
@@ -545,7 +550,7 @@ int main(int argc, char **argv)
|
||||
|
||||
ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms,
|
||||
dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch,
|
||||
slot,harq_pid, is_crnti, llr8_flag);
|
||||
slot,harq_pid, is_crnti);
|
||||
|
||||
vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT);
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ uint16_t sl_ahead=0;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
THREAD_STRUCT thread_struct;
|
||||
nfapi_ue_release_request_body_t release_rntis;
|
||||
uint32_t N_RB_DL = 106;
|
||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||
instance_t DUuniqInstance=0;
|
||||
instance_t CUuniqInstance=0;
|
||||
@@ -105,6 +104,10 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer
|
||||
return 0;
|
||||
}
|
||||
|
||||
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// dummy functions
|
||||
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
|
||||
|
||||
@@ -207,10 +210,9 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
|
||||
int pdsch_AntennaPorts,
|
||||
int pusch_AntennaPorts,
|
||||
NR_ServingCellConfigCommon_t *scc
|
||||
);
|
||||
NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
int generate_dlsch_header(unsigned char *mac_header,
|
||||
unsigned char num_sdus,
|
||||
@@ -267,9 +269,9 @@ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLay
|
||||
void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0];
|
||||
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0];
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
/* manually set free CCE to 0 */
|
||||
@@ -279,17 +281,17 @@ void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
sched_ctrl->coreset = get_coreset(module_id, scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->cce_index = 0;
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
nr_set_pdsch_semi_static(NULL,
|
||||
scc,
|
||||
UE_info->CellGroup[0],
|
||||
UE_info->CellGroup,
|
||||
sched_ctrl->active_bwp,
|
||||
NULL,
|
||||
/* tda = */ 2,
|
||||
/* tda = */ 0,
|
||||
g_nrOfLayers,
|
||||
sched_ctrl,
|
||||
ps);
|
||||
@@ -311,8 +313,7 @@ void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
ps->nrOfLayers)
|
||||
>> 3;
|
||||
ps->nrOfLayers) >> 3;
|
||||
|
||||
/* the simulator assumes the HARQ PID is equal to the slot number */
|
||||
sched_pdsch->dl_harq_pid = slot;
|
||||
@@ -648,15 +649,15 @@ int main(int argc, char **argv)
|
||||
dmrs_arg[i] = atoi(argv[optind++]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'X':
|
||||
strncpy(gNBthreads, optarg, sizeof(gNBthreads));
|
||||
gNBthreads[sizeof(gNBthreads)-1]=0;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
|
||||
argv[0]);
|
||||
printf("-h This message\n");
|
||||
printf("-L <log level, 0(errors), 1(warning), 2(analysis), 3(info), 4(debug), 5(trace)>\n");
|
||||
@@ -665,7 +666,7 @@ int main(int argc, char **argv)
|
||||
printf("-n Number of frames to simulate\n");
|
||||
printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n");
|
||||
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
|
||||
printf("-t Delay spread for multipath channel\n");
|
||||
//printf("-t Delay spread for multipath channel\n");
|
||||
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");
|
||||
@@ -835,8 +836,7 @@ int main(int argc, char **argv)
|
||||
gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
|
||||
phy_init_nr_gNB(gNB,0,1);
|
||||
N_RB_DL = gNB->frame_parms.N_RB_DL;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
|
||||
UE_info->num_UEs=1;
|
||||
NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0];
|
||||
|
||||
// stub to configure frame_parms
|
||||
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
|
||||
@@ -851,10 +851,14 @@ int main(int argc, char **argv)
|
||||
|
||||
double fs,bw;
|
||||
|
||||
if (mu == 1 && N_RB_DL == 217) {
|
||||
if (mu == 0 && N_RB_DL == 25) {
|
||||
fs = 7.68e6;
|
||||
bw = 5e6;
|
||||
}
|
||||
else if (mu == 1 && N_RB_DL == 217) {
|
||||
fs = 122.88e6;
|
||||
bw = 80e6;
|
||||
}
|
||||
}
|
||||
else if (mu == 1 && N_RB_DL == 245) {
|
||||
fs = 122.88e6;
|
||||
bw = 90e6;
|
||||
@@ -867,14 +871,18 @@ int main(int argc, char **argv)
|
||||
fs = 61.44e6;
|
||||
bw = 40e6;
|
||||
}
|
||||
else if (mu == 1 && N_RB_DL == 133) {
|
||||
else if (mu == 1 && N_RB_DL == 133) {
|
||||
fs = 61.44e6;
|
||||
bw = 50e6;
|
||||
}
|
||||
else if (mu == 1 && N_RB_DL == 162) {
|
||||
else if (mu == 1 && N_RB_DL == 162) {
|
||||
fs = 61.44e6;
|
||||
bw = 60e6;
|
||||
}
|
||||
else if (mu == 1 && N_RB_DL == 24) {
|
||||
fs = 15.36e6;
|
||||
bw = 10e6;
|
||||
}
|
||||
else if (mu == 3 && N_RB_DL == 66) {
|
||||
fs = 122.88e6;
|
||||
bw = 100e6;
|
||||
@@ -1096,10 +1104,10 @@ int main(int argc, char **argv)
|
||||
|
||||
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
|
||||
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
|
||||
|
||||
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
gNB_mac->pdcch_cand[i] = 0;
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ nfapi_mode_t nfapi_mod;
|
||||
nfapi_mode_t nfapi_getmode(void) {
|
||||
return nfapi_mod;
|
||||
}
|
||||
void nfapi_setmode(nfapi_mode_t nfapi_mode) {}
|
||||
|
||||
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
|
||||
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
|
||||
void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
|
||||
|
||||
@@ -97,6 +97,10 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer
|
||||
return 0;
|
||||
}
|
||||
|
||||
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rrc_data_ind(
|
||||
const protocol_ctxt_t *const ctxt_pP,
|
||||
@@ -236,7 +240,7 @@ int main(int argc, char **argv){
|
||||
int i, l, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
|
||||
int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
|
||||
uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
|
||||
uint8_t frame = 1, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
|
||||
uint8_t config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
|
||||
uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
|
||||
uint32_t tx_lev = 10000, prach_errors = 0; //,tx_lev_dB;
|
||||
uint64_t SSB_positions = 0x01;
|
||||
@@ -532,7 +536,7 @@ int main(int argc, char **argv){
|
||||
frame_parms->N_RB_UL = N_RB_UL;
|
||||
frame_parms->threequarter_fs = threequarter_fs;
|
||||
frame_parms->frame_type = TDD;
|
||||
frame_parms->freq_range = (mu==1 ? nr_FR1 : nr_FR2);
|
||||
frame_parms->freq_range = (mu != 3 ? nr_FR1 : nr_FR2);
|
||||
frame_parms->numerology_index = mu;
|
||||
|
||||
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
|
||||
@@ -542,9 +546,11 @@ int main(int argc, char **argv){
|
||||
frame_parms->numerology_index,
|
||||
frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index));
|
||||
|
||||
uint8_t subframe = slot/frame_parms->slots_per_subframe;
|
||||
uint8_t frame = 1;
|
||||
uint8_t subframe = 9;
|
||||
uint8_t slot = 10 * frame_parms->slots_per_subframe - 1;
|
||||
|
||||
if (config_index<67 && mu==1) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); }
|
||||
if (config_index<67 && mu != 3) { prach_sequence_length=0; slot = subframe * frame_parms->slots_per_subframe; }
|
||||
uint16_t N_ZC = prach_sequence_length == 0 ? 839 : 139;
|
||||
|
||||
printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length);
|
||||
@@ -565,9 +571,11 @@ int main(int argc, char **argv){
|
||||
ru->gNB_list[0] = gNB;
|
||||
gNB->gNB_config.carrier_config.num_tx_ant.value = 1;
|
||||
gNB->gNB_config.carrier_config.num_rx_ant.value = 1;
|
||||
if (mu==1)
|
||||
if (mu == 0)
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 7;
|
||||
else if (mu == 1)
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 6;
|
||||
else if (mu==3)
|
||||
else if (mu == 3)
|
||||
gNB->gNB_config.tdd_table.tdd_period.value = 3;
|
||||
else {
|
||||
printf("unsupported numerology %d\n",mu);
|
||||
@@ -581,7 +589,7 @@ int main(int argc, char **argv){
|
||||
|
||||
int ret = get_nr_prach_info_from_index(config_index,
|
||||
(int)frame,
|
||||
(int)slot_gNB,
|
||||
(int)slot,
|
||||
absoluteFrequencyPointA,
|
||||
mu,
|
||||
frame_parms->frame_type,
|
||||
@@ -713,12 +721,7 @@ int main(int argc, char **argv){
|
||||
bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index);
|
||||
AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n", bw, frame_parms->numerology_index, N_RB_UL);
|
||||
|
||||
if (bw <= 30.72e6)
|
||||
fs = 30.72e6;
|
||||
else if (bw <= 61.44e6)
|
||||
fs = 61.44e6;
|
||||
else if (bw <= 122.88e6)
|
||||
fs = 122.88e6;
|
||||
fs = frame_parms->samples_per_subframe * 1e3;
|
||||
|
||||
LOG_I(PHY,"Running with bandwidth %f Hz, fs %f samp/s, FRAME_LENGTH_COMPLEX_SAMPLES %d\n",bw,fs,FRAME_LENGTH_COMPLEX_SAMPLES);
|
||||
|
||||
|
||||
@@ -47,12 +47,13 @@
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
|
||||
|
||||
THREAD_STRUCT thread_struct;
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
double cpuf;
|
||||
//uint8_t nfapi_mode = 0;
|
||||
|
||||
@@ -47,13 +47,16 @@
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
|
||||
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
|
||||
//#define DEBUG_NR_ULSCHSIM
|
||||
|
||||
THREAD_STRUCT thread_struct;
|
||||
PHY_VARS_gNB *gNB;
|
||||
PHY_VARS_NR_UE *UE;
|
||||
RAN_CONTEXT_t RC;
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
|
||||
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
|
||||
|
||||
@@ -137,6 +140,7 @@ int main(int argc, char **argv)
|
||||
uint16_t nb_symb_sch = 12;
|
||||
uint16_t nb_rb = 50;
|
||||
uint8_t Imcs = 9;
|
||||
uint8_t Nl = 1;
|
||||
|
||||
double DS_TDL = .03;
|
||||
|
||||
@@ -150,7 +154,7 @@ int main(int argc, char **argv)
|
||||
randominit(0);
|
||||
|
||||
//while ((c = getopt(argc, argv, "df:hpg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "hg:n:s:S:py:z:M:N:R:F:m:l:r:W:")) != -1) {
|
||||
switch (c) {
|
||||
/*case 'f':
|
||||
write_output_file = 1;
|
||||
@@ -251,7 +255,7 @@ int main(int argc, char **argv)
|
||||
case 'y':
|
||||
n_tx = atoi(optarg);
|
||||
|
||||
if ((n_tx == 0) || (n_tx > 2)) {
|
||||
if ((n_tx == 0) || (n_tx > 4)) {
|
||||
printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx);
|
||||
exit(-1);
|
||||
}
|
||||
@@ -261,7 +265,7 @@ int main(int argc, char **argv)
|
||||
case 'z':
|
||||
n_rx = atoi(optarg);
|
||||
|
||||
if ((n_rx == 0) || (n_rx > 2)) {
|
||||
if ((n_rx == 0) || (n_rx > 4)) {
|
||||
printf("Unsupported number of RX antennas %d. Exiting.\n", n_rx);
|
||||
exit(-1);
|
||||
}
|
||||
@@ -299,6 +303,10 @@ int main(int argc, char **argv)
|
||||
printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase);
|
||||
break;*/
|
||||
|
||||
case 'W':
|
||||
Nl = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
Imcs = atoi(optarg);
|
||||
#ifdef DEBUG_NR_ULSCHSIM
|
||||
@@ -335,13 +343,14 @@ int main(int argc, char **argv)
|
||||
printf("-z Number of RX antennas used in UE\n");
|
||||
//printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n");
|
||||
//printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n");
|
||||
printf("-W number of layer\n");
|
||||
printf("-M Multiple SSB positions in burst\n");
|
||||
printf("-N Nid_cell\n");
|
||||
printf("-R N_RB_UL\n");
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-m\n");
|
||||
printf("-l\n");
|
||||
printf("-r\n");
|
||||
printf("-m MCS\n");
|
||||
printf("-l number of symbol\n");
|
||||
printf("-r number of RB\n");
|
||||
//printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
//printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
|
||||
//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
|
||||
@@ -359,8 +368,8 @@ int main(int argc, char **argv)
|
||||
snr1 = snr0 + 10;
|
||||
|
||||
gNB2UE = new_channel_desc_scm(n_tx,
|
||||
n_rx,
|
||||
channel_model,
|
||||
n_rx,
|
||||
channel_model,
|
||||
61.44e6, //N_RB2sampling_rate(N_RB_DL),
|
||||
40e6, //N_RB2channel_bandwidth(N_RB_DL),
|
||||
DS_TDL,
|
||||
@@ -383,8 +392,6 @@ int main(int argc, char **argv)
|
||||
initTpool(tp_param, gNB->threadPool, true);
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
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;
|
||||
frame_parms->N_RB_DL = N_RB_DL;
|
||||
frame_parms->N_RB_UL = N_RB_UL;
|
||||
frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
|
||||
@@ -392,6 +399,9 @@ int main(int argc, char **argv)
|
||||
|
||||
memcpy(&gNB->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
|
||||
gNB->frame_parms.nb_antennas_tx = 1;
|
||||
gNB->frame_parms.nb_antennas_rx = n_rx;
|
||||
|
||||
nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions);
|
||||
|
||||
phy_init_nr_gNB(gNB, 0, 1); //lowmem
|
||||
@@ -400,6 +410,9 @@ int main(int argc, char **argv)
|
||||
UE = malloc(sizeof(PHY_VARS_NR_UE));
|
||||
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
|
||||
UE->frame_parms.nb_antennas_tx = n_tx;
|
||||
UE->frame_parms.nb_antennas_rx = 1;
|
||||
|
||||
//phy_init_nr_top(frame_parms);
|
||||
if (init_nr_ue_signal(UE, 1) != 0) {
|
||||
printf("Error at UE NR initialisation.\n");
|
||||
@@ -407,7 +420,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
for (sf = 0; sf < 2; sf++) {
|
||||
UE->ulsch[sf][0] = new_nr_ue_ulsch(N_RB_UL, 8);
|
||||
UE->ulsch[sf][0] = new_nr_ue_ulsch(N_RB_UL, 8, frame_parms);
|
||||
if (!UE->ulsch[sf][0]) {
|
||||
printf("Can't get ue ulsch structures.\n");
|
||||
exit(-1);
|
||||
@@ -421,8 +434,7 @@ int main(int argc, char **argv)
|
||||
uint8_t length_dmrs = 1;
|
||||
uint8_t N_PRB_oh;
|
||||
uint16_t N_RE_prime,code_rate;
|
||||
unsigned char mod_order;
|
||||
uint8_t Nl = 1;
|
||||
unsigned char mod_order;
|
||||
uint8_t rvidx = 0;
|
||||
uint8_t UE_id = 0;
|
||||
|
||||
@@ -432,9 +444,12 @@ int main(int argc, char **argv)
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[0][0];
|
||||
|
||||
if ((Nl==4)||(Nl==3))
|
||||
nb_re_dmrs = nb_re_dmrs*2;
|
||||
|
||||
mod_order = nr_get_Qm_ul(Imcs, 0);
|
||||
code_rate = nr_get_code_rate_ul(Imcs, 0);
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl);
|
||||
TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
|
||||
|
||||
printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
|
||||
@@ -447,7 +462,7 @@ int main(int argc, char **argv)
|
||||
rel15_ul->pusch_data.rv_index = rvidx;
|
||||
rel15_ul->nrOfLayers = Nl;
|
||||
rel15_ul->target_code_rate = code_rate;
|
||||
rel15_ul->pusch_data.tb_size = TBS/8;
|
||||
rel15_ul->pusch_data.tb_size = TBS>>3;
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
double modulated_input[16 * 68 * 384]; // [hna] 16 segments, 68*Zc
|
||||
@@ -474,7 +489,9 @@ int main(int argc, char **argv)
|
||||
harq_process_ul_ue->pusch_pdu.nr_of_symbols = nb_symb_sch;
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb*nb_codewords;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.rv_index = rvidx;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS/8;
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size = TBS>>3;
|
||||
harq_process_ul_ue->pusch_pdu.target_code_rate = code_rate;
|
||||
harq_process_ul_ue->pusch_pdu.qam_mod_order = mod_order;
|
||||
unsigned char *test_input = harq_process_ul_ue->a;
|
||||
|
||||
///////////
|
||||
@@ -610,7 +627,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
for (sf = 0; sf < 2; sf++)
|
||||
free_nr_ue_ulsch(&UE->ulsch[sf][0], N_RB_UL);
|
||||
free_nr_ue_ulsch(&UE->ulsch[sf][0], N_RB_UL, frame_parms);
|
||||
|
||||
term_nr_ue_signal(UE, 1);
|
||||
free(UE);
|
||||
|
||||
|
||||
+292
-210
@@ -91,7 +91,6 @@ double cpuf;
|
||||
uint64_t downlink_frequency[MAX_NUM_CCs][4];
|
||||
THREAD_STRUCT thread_struct;
|
||||
nfapi_ue_release_request_body_t release_rntis;
|
||||
uint32_t N_RB_DL = 106;
|
||||
|
||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||
instance_t DUuniqInstance=0;
|
||||
@@ -100,6 +99,11 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer
|
||||
transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
|
||||
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
|
||||
@@ -298,10 +302,9 @@ int main(int argc, char **argv)
|
||||
int gNB_id = 0;
|
||||
int ap;
|
||||
int tx_offset;
|
||||
int32_t txlev=0;
|
||||
int32_t txlev_sum = 0, atxlev[4];
|
||||
int start_rb = 0;
|
||||
int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
|
||||
float target_error_rate = 0.01;
|
||||
int print_perf = 0;
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
int msg3_flag = 0;
|
||||
@@ -309,7 +312,7 @@ int main(int argc, char **argv)
|
||||
float roundStats[100];
|
||||
double effRate[100];
|
||||
double effTP[100];
|
||||
//float eff_tp_check = 0.7;
|
||||
float eff_tp_check = 0.7;
|
||||
uint8_t snrRun;
|
||||
int prb_inter = 0;
|
||||
|
||||
@@ -317,13 +320,13 @@ int main(int argc, char **argv)
|
||||
int modify_dmrs = 0;
|
||||
/* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
|
||||
int ptrs_arg[2] = {-1,-1};// Invalid values
|
||||
/* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */
|
||||
int dmrs_arg[2] = {-1,-1};// Invalid values
|
||||
/* mapping type = dmrs_arg[0], Add Pos = dmrs_arg[1], dmrs config type = dmrs_arg[2] */
|
||||
int dmrs_arg[3] = {-1,-1,-1};// Invalid values
|
||||
uint16_t ptrsSymPos = 0;
|
||||
uint16_t ptrsSymbPerSlot = 0;
|
||||
uint16_t ptrsRePerSymb = 0;
|
||||
|
||||
uint8_t transform_precoding = 1; // 0 - ENABLE, 1 - DISABLE
|
||||
uint8_t transform_precoding = transformPrecoder_disabled; // 0 - ENABLE, 1 - DISABLE
|
||||
uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
uint8_t mcs_table = 0;
|
||||
|
||||
@@ -346,7 +349,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:ikl:m:n:p:r:s:t:u:w: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:t:u:w:y:z:F:G:H:M:N:PR:S:T:U:L:ZW:")) != -1) {
|
||||
printf("handling optarg %c\n",c);
|
||||
switch (c) {
|
||||
|
||||
@@ -380,8 +383,8 @@ int main(int argc, char **argv)
|
||||
scg_fd = fopen(optarg, "r");
|
||||
|
||||
if (scg_fd == NULL) {
|
||||
printf("Error opening %s\n", optarg);
|
||||
exit(-1);
|
||||
printf("Error opening %s\n", optarg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -454,7 +457,11 @@ int main(int argc, char **argv)
|
||||
case 'm':
|
||||
Imcs = atoi(optarg);
|
||||
break;
|
||||
|
||||
|
||||
case 'W':
|
||||
precod_nbr_layers = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_trials = atoi(optarg);
|
||||
break;
|
||||
@@ -482,11 +489,10 @@ int main(int argc, char **argv)
|
||||
start_rb = atoi(optarg);
|
||||
break;
|
||||
|
||||
/*
|
||||
case 't':
|
||||
eff_tp_check = (float)atoi(optarg)/100;
|
||||
break;
|
||||
*/
|
||||
|
||||
/*
|
||||
case 'r':
|
||||
ricean_factor = pow(10,-.1*atof(optarg));
|
||||
@@ -503,32 +509,26 @@ int main(int argc, char **argv)
|
||||
|
||||
case 'y':
|
||||
n_tx = atoi(optarg);
|
||||
|
||||
if ((n_tx == 0) || (n_tx > 2)) {
|
||||
printf("Unsupported number of tx antennas %d\n", n_tx);
|
||||
exit(-1);
|
||||
if ((n_tx == 0) || (n_tx > 4)) {
|
||||
printf("Unsupported number of tx antennas %d\n", n_tx);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
n_rx = atoi(optarg);
|
||||
|
||||
if ((n_rx == 0) || (n_rx > 8)) {
|
||||
printf("Unsupported number of rx antennas %d\n", n_rx);
|
||||
exit(-1);
|
||||
printf("Unsupported number of rx antennas %d\n", n_rx);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
input_fd = fopen(optarg, "r");
|
||||
|
||||
if (input_fd == NULL) {
|
||||
printf("Problem with filename %s\n", optarg);
|
||||
exit(-1);
|
||||
printf("Problem with filename %s\n", optarg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
@@ -586,18 +586,15 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
|
||||
transform_precoding = 0; // enabled
|
||||
transform_precoding = transformPrecoder_enabled;
|
||||
num_dmrs_cdm_grps_no_data = 2;
|
||||
mcs_table = 3;
|
||||
|
||||
printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding);
|
||||
|
||||
printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId -Z Enable SC-FDMA in Uplink \n", argv[0]);
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId -Z Enable SC-FDMA in Uplink \n", argv[0]);
|
||||
//printf("-d Use TDD\n");
|
||||
printf("-d Introduce delay in terms of number of samples\n");
|
||||
printf("-f Number of frames to simulate\n");
|
||||
@@ -609,17 +606,17 @@ int main(int argc, char **argv)
|
||||
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("-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");
|
||||
printf("-y Number of TX antennas used at UE\n");
|
||||
printf("-z Number of RX antennas used at gNB\n");
|
||||
printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n");
|
||||
//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
|
||||
printf("-F Input filename (.txt format) for RX conformance testing\n");
|
||||
printf("-G Offset of samples to read from file (0 default)\n");
|
||||
printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");
|
||||
printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");
|
||||
printf("-M Multiple SSB positions in burst\n");
|
||||
printf("-N Nid_cell\n");
|
||||
printf("-O oversampling factor (1,2,4,8,16)\n");
|
||||
@@ -631,6 +628,7 @@ int main(int argc, char **argv)
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
|
||||
printf("-Q If -F used, read parameters from file\n");
|
||||
printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n");
|
||||
printf("-W Num of layer for PUSCH\n");
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
@@ -651,16 +649,37 @@ int main(int argc, char **argv)
|
||||
double sampling_frequency;
|
||||
double bandwidth;
|
||||
|
||||
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 (mu == 0 && N_RB_UL == 25 ) {
|
||||
sampling_frequency = 7.68;
|
||||
bandwidth = 5;
|
||||
}
|
||||
else if (mu == 1 && N_RB_UL == 273) {
|
||||
sampling_frequency = 122.88;
|
||||
bandwidth = 100;
|
||||
}
|
||||
else if (mu == 1 && N_RB_UL == 217) {
|
||||
sampling_frequency = 122.88;
|
||||
bandwidth = 80;
|
||||
}
|
||||
else if (mu == 1 && N_RB_UL == 106) {
|
||||
sampling_frequency = 61.44;
|
||||
bandwidth = 40;
|
||||
}
|
||||
else if (mu == 1 && N_RB_UL == 24) {
|
||||
sampling_frequency = 15.36;
|
||||
bandwidth = 10;
|
||||
}
|
||||
else if (mu == 3 && N_RB_UL == 32) {
|
||||
sampling_frequency = 61.44;
|
||||
bandwidth = 50;
|
||||
}
|
||||
else {
|
||||
printf("Add N_RB_UL %d\n",N_RB_UL);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
LOG_I( PHY,"++++++++++++++++++++++++++++++++++++++++++++++%i+++++++++++++++++++++++++++++++++++++++++",loglvl);
|
||||
|
||||
if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75;
|
||||
|
||||
UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model,
|
||||
@@ -747,7 +766,8 @@ int main(int argc, char **argv)
|
||||
|
||||
// TODO do a UECAP for phy-sim
|
||||
const gNB_RrcConfigurationReq conf = {
|
||||
.pdsch_AntennaPorts = { .N1 = n_tx, .N2 = 1, .XP = 1 },
|
||||
.pdsch_AntennaPorts = { .N1 = 1, .N2 = 1, .XP = 1 },
|
||||
.pusch_AntennaPorts = n_rx,
|
||||
.minRXTXTIME = 0,
|
||||
.do_CSIRS = 0,
|
||||
.do_SRS = 0,
|
||||
@@ -760,17 +780,18 @@ int main(int argc, char **argv)
|
||||
/* RRC parameter validation for secondaryCellGroup */
|
||||
fix_scd(scd);
|
||||
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
|
||||
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
|
||||
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
gNB->if_inst->NR_PHY_config_req = nr_phy_config_request;
|
||||
// common configuration
|
||||
rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL);
|
||||
// UE dedicated configuration
|
||||
rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
|
||||
frame_parms->nb_antennas_tx = n_tx;
|
||||
rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1,
|
||||
secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, secondaryCellGroup);
|
||||
frame_parms->nb_antennas_tx = 1;
|
||||
frame_parms->nb_antennas_rx = n_rx;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
cfg->carrier_config.num_tx_ant.value = n_tx;
|
||||
cfg->carrier_config.num_tx_ant.value = 1;
|
||||
cfg->carrier_config.num_rx_ant.value = n_rx;
|
||||
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,0,0x01);
|
||||
phy_init_nr_gNB(gNB,0,1);
|
||||
@@ -787,6 +808,8 @@ int main(int argc, char **argv)
|
||||
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*));
|
||||
PHY_vars_UE_g[0][0] = UE;
|
||||
memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));
|
||||
UE->frame_parms.nb_antennas_tx = n_tx;
|
||||
UE->frame_parms.nb_antennas_rx = 1;
|
||||
|
||||
if (init_nr_ue_signal(UE, 1) != 0) {
|
||||
printf("Error at UE NR initialisation\n");
|
||||
@@ -839,7 +862,7 @@ int main(int argc, char **argv)
|
||||
|
||||
unsigned char *estimated_output_bit;
|
||||
unsigned char *test_input_bit;
|
||||
uint32_t errors_decoding = 0;
|
||||
uint32_t errors_decoding = 0;
|
||||
|
||||
|
||||
test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
|
||||
@@ -872,23 +895,20 @@ int main(int argc, char **argv)
|
||||
|
||||
/* validate parameters othwerwise default values are used */
|
||||
/* -U flag can be used to set DMRS parameters*/
|
||||
if(modify_dmrs)
|
||||
{
|
||||
if(modify_dmrs) {
|
||||
if(dmrs_arg[0] == 0)
|
||||
{
|
||||
mapping_type = typeA;
|
||||
}
|
||||
else if (dmrs_arg[0] == 1)
|
||||
{
|
||||
mapping_type = typeB;
|
||||
}
|
||||
/* Additional DMRS positions */
|
||||
if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
|
||||
{
|
||||
add_pos = dmrs_arg[1];
|
||||
}
|
||||
/* DMRS Conf Type 1 or 2 */
|
||||
if(dmrs_arg[2] == 1)
|
||||
dmrs_config_type = pusch_dmrs_type1;
|
||||
else if(dmrs_arg[2] == 2)
|
||||
dmrs_config_type = pusch_dmrs_type2;
|
||||
}
|
||||
printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos );
|
||||
|
||||
uint8_t length_dmrs = pusch_len1;
|
||||
uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs, start_symbol, NR_MIB__dmrs_TypeA_Position_pos2);
|
||||
@@ -896,22 +916,25 @@ int main(int argc, char **argv)
|
||||
printf("num dmrs sym %d\n",number_dmrs_symbols);
|
||||
uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
|
||||
|
||||
// if transform precoding is enabled
|
||||
if (transform_precoding == 0) {
|
||||
if ((UE->frame_parms.nb_antennas_tx==4)&&(precod_nbr_layers==4))
|
||||
num_dmrs_cdm_grps_no_data = 2;
|
||||
|
||||
if (transform_precoding == transformPrecoder_enabled) {
|
||||
|
||||
AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
|
||||
|
||||
int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb);
|
||||
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
|
||||
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
|
||||
|
||||
dmrs_config_type = pusch_dmrs_type1;
|
||||
nb_re_dmrs = 6;
|
||||
|
||||
printf("[ULSIM]: TRANSFORM PRECODING ENABLED. Num RBs: %d, index for DMRS_SEQ: %d\n", nb_rb, index);
|
||||
}
|
||||
|
||||
nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data;
|
||||
nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data;
|
||||
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, precod_nbr_layers);
|
||||
unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
|
||||
|
||||
|
||||
@@ -936,17 +959,12 @@ int main(int argc, char **argv)
|
||||
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
|
||||
|
||||
/* -T option enable PTRS */
|
||||
if(enable_ptrs)
|
||||
{
|
||||
if(enable_ptrs) {
|
||||
/* validate parameters othwerwise default values are used */
|
||||
if(ptrs_arg[0] == 0 || ptrs_arg[0] == 1 || ptrs_arg[0] == 2 )
|
||||
{
|
||||
ptrs_time_density = ptrs_arg[0];
|
||||
}
|
||||
if(ptrs_arg[1] == 2 || ptrs_arg[1] == 4 )
|
||||
{
|
||||
ptrs_freq_density = ptrs_arg[1];
|
||||
}
|
||||
pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
|
||||
printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
|
||||
}
|
||||
@@ -1062,7 +1080,7 @@ int main(int argc, char **argv)
|
||||
uint8_t round = 0;
|
||||
|
||||
crc_status = 1;
|
||||
errors_decoding = 0;
|
||||
errors_decoding = 0;
|
||||
memset((void*)roundStats,0,50*sizeof(roundStats[0]));
|
||||
while (round<max_rounds && crc_status) {
|
||||
round_trials[round][snrRun]++;
|
||||
@@ -1109,12 +1127,12 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->qam_mod_order = mod_order;
|
||||
pusch_pdu->transform_precoding = transform_precoding;
|
||||
pusch_pdu->data_scrambling_id = *scc->physCellId;
|
||||
pusch_pdu->nrOfLayers = 1;
|
||||
pusch_pdu->nrOfLayers = precod_nbr_layers;
|
||||
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask;
|
||||
pusch_pdu->dmrs_config_type = dmrs_config_type;
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
pusch_pdu->scid = 0;
|
||||
pusch_pdu->dmrs_ports = 1;
|
||||
pusch_pdu->dmrs_ports = ((1<<precod_nbr_layers)-1);
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||
pusch_pdu->resource_alloc = 1;
|
||||
pusch_pdu->rb_start = start_rb;
|
||||
@@ -1134,7 +1152,7 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
|
||||
// if transform precoding is enabled
|
||||
if (transform_precoding == 0) {
|
||||
if (transform_precoding == transformPrecoder_enabled) {
|
||||
|
||||
pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2
|
||||
pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2
|
||||
@@ -1181,7 +1199,9 @@ int main(int argc, char **argv)
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dmrs_ports = ((1<<precod_nbr_layers)-1);
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.target_code_rate = code_rate;
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS/8;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
|
||||
@@ -1190,13 +1210,13 @@ int main(int argc, char **argv)
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding;
|
||||
|
||||
// if transform precoding is enabled
|
||||
if (transform_precoding == 0) {
|
||||
if (transform_precoding == transformPrecoder_enabled) {
|
||||
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2
|
||||
ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2
|
||||
@@ -1224,43 +1244,83 @@ int main(int argc, char **argv)
|
||||
LOG_D(PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(UE,
|
||||
slot,
|
||||
&UE->frame_parms,1);
|
||||
&UE->frame_parms,
|
||||
UE->frame_parms.nb_antennas_tx);
|
||||
|
||||
|
||||
if (n_trials==1) {
|
||||
LOG_M("txsig0.m","txs0", UE->common_vars.txdata[0],frame_parms->samples_per_subframe*10,1,1);
|
||||
LOG_M("txsig0.m","txs0", &UE->common_vars.txdata[0][slot_offset],slot_length,1,1);
|
||||
LOG_M("txsig0F.m","txs0F", UE->common_vars.txdataF[0],frame_parms->ofdm_symbol_size*14,1,1);
|
||||
if (precod_nbr_layers > 1) {
|
||||
LOG_M("txsig1.m","txs1", &UE->common_vars.txdata[1][slot_offset],slot_length,1,1);
|
||||
LOG_M("txsig1F.m","txs1F", UE->common_vars.txdataF[1],frame_parms->ofdm_symbol_size*14,1,1);
|
||||
if (precod_nbr_layers==4) {
|
||||
LOG_M("txsig2.m","txs2", &UE->common_vars.txdata[2][slot_offset],slot_length,1,1);
|
||||
LOG_M("txsig3.m","txs3", &UE->common_vars.txdata[3][slot_offset],slot_length,1,1);
|
||||
LOG_M("txsig2F.m","txs2F", UE->common_vars.txdataF[2],frame_parms->ofdm_symbol_size*14,1,1);
|
||||
LOG_M("txsig3F.m","txs3F", UE->common_vars.txdataF[3],frame_parms->ofdm_symbol_size*14,1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////
|
||||
////////////////////////////////////////////////////
|
||||
tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
|
||||
txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
txlev_sum = 0;
|
||||
for (int aa=0; aa<UE->frame_parms.nb_antennas_tx; aa++) {
|
||||
atxlev[aa] = signal_energy(&UE->common_vars.txdata[aa][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
|
||||
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
|
||||
}
|
||||
else n_trials = 1;
|
||||
|
||||
if (input_fd == NULL ) {
|
||||
txlev_sum += atxlev[aa];
|
||||
|
||||
sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
|
||||
if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,atxlev[aa],10*log10((double)atxlev[aa]),txlev_sum);
|
||||
}
|
||||
}
|
||||
else
|
||||
n_trials = 1;
|
||||
|
||||
if (input_fd == NULL) {
|
||||
// Justification of division by precod_nbr_layers:
|
||||
// When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4.
|
||||
sigma_dB = 10 * log10((double)txlev_sum/precod_nbr_layers * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;;
|
||||
sigma = pow(10,sigma_dB/10);
|
||||
|
||||
|
||||
if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)
|
||||
frame_parms->ofdm_symbol_size/(12*nb_rb));
|
||||
if(n_trials==1) printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev_sum),(double)(double)
|
||||
frame_parms->ofdm_symbol_size/(12*nb_rb));
|
||||
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (int aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
for (int aa=0; aa<UE->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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (UE2gNB->max_Doppler == 0) {
|
||||
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0);
|
||||
// The multipath_channel() function calculates a channel matrix with only 1's. So the channel rank is 1, and we
|
||||
// cannot use multi-layer. To solve this issue, for now we use the H_awgn_mimo matrix for multi-layer.
|
||||
if (precod_nbr_layers == 1) {
|
||||
if (UE2gNB->max_Doppler == 0) {
|
||||
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials==1)?1:0);
|
||||
} else {
|
||||
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
|
||||
}
|
||||
} else {
|
||||
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, 2*slot_length, 0);
|
||||
double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
|
||||
{0.2, 1.0, 0.2, 0.1}, //rx 1
|
||||
{0.1, 0.2, 1.0, 0.2}, //rx 2
|
||||
{0.05, 0.1, 0.2, 1.0}}; //rx 3
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (ap = 0; ap < frame_parms->nb_antennas_rx; ap++) {
|
||||
// sum up signals from different Tx antennas
|
||||
r_re[ap][i] = 0;
|
||||
r_im[ap][i] = 0;
|
||||
for (int aa=0; aa<n_tx; aa++) {
|
||||
r_re[ap][i] += s_re[aa][i]*H_awgn_mimo[ap][aa];
|
||||
r_im[ap][i] += s_im[aa][i]*H_awgn_mimo[ap][aa];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<slot_length; i++) {
|
||||
for (ap=0; ap<frame_parms->nb_antennas_rx; ap++) {
|
||||
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
|
||||
@@ -1284,7 +1344,7 @@ int main(int argc, char **argv)
|
||||
pusch_pdu->ul_dmrs_symb_pos);
|
||||
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymPos, pusch_pdu->start_symbol_index, pusch_pdu->nr_of_symbols);
|
||||
ptrsRePerSymb = ((pusch_pdu->rb_size + ptrs_freq_density - 1)/ptrs_freq_density);
|
||||
printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
|
||||
LOG_D(PHY,"[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1294,130 +1354,152 @@ int main(int argc, char **argv)
|
||||
gNB->UL_INFO.rx_ind.number_of_pdus = 0;
|
||||
gNB->UL_INFO.crc_ind.number_crcs = 0;
|
||||
|
||||
phy_procedures_gNB_common_RX(gNB, frame, slot);
|
||||
phy_procedures_gNB_common_RX(gNB, frame, slot);
|
||||
|
||||
ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);
|
||||
ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot);
|
||||
|
||||
if (n_trials==1 && round==0) {
|
||||
LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1);
|
||||
|
||||
LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0]+start_symbol*frame_parms->ofdm_symbol_size,nb_symb_sch*frame_parms->ofdm_symbol_size,1,1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (n_trials == 1 && round==0) {
|
||||
#ifdef __AVX2__
|
||||
__attribute__((unused))
|
||||
int off = ((nb_rb&1) == 1)? 4:0;
|
||||
#else
|
||||
__attribute__((unused))
|
||||
int off = 0;
|
||||
#endif
|
||||
|
||||
LOG_M("rxsigF0_ext.m","rxsF0_ext",
|
||||
&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);
|
||||
LOG_M("rxsigF0_comp.m","rxsF0_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(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("chmagF0.m","chmF0",
|
||||
&gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(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("chmagbF0.m","chmbF0",
|
||||
&gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
|
||||
if (n_rx == 2) {
|
||||
LOG_MM("rxsigF0_comp.m","rxsF1_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(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_MM("rxsigF0_ext.m","rxsF1_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[1][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_MM("chestF0_ext.m","chF1_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(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);
|
||||
LOG_MM("chmagF0.m","chmF1",
|
||||
&gNB->pusch_vars[0]->ul_ch_mag[1][start_symbol*(off+(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_MM("chmagbF0.m","chmbF1",
|
||||
&gNB->pusch_vars[0]->ul_ch_magb[1][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
|
||||
} else if (n_rx == 4) {
|
||||
LOG_MM("rxsigF0_comp.m","rxsF1_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[1][start_symbol*(off+(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_MM("rxsigF0_comp.m","rxsF2_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[2][start_symbol*(off+(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_MM("rxsigF0_comp.m","rxsF3_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[3][start_symbol*(off+(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_MM("rxsigF0_ext.m","rxsF1_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[1][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_MM("rxsigF0_ext.m","rxsF2_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[2][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_MM("rxsigF0_ext.m","rxsF3_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[3][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_MM("chestF0_ext.m","chF1_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[1][(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);
|
||||
LOG_MM("chestF0_ext.m","chF2_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[2][(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);
|
||||
LOG_MM("chestF0_ext.m","chF3_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(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);
|
||||
LOG_MM("chmagF0.m","chmF1",
|
||||
&gNB->pusch_vars[0]->ul_ch_mag[1][start_symbol*(off+(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_MM("chmagF0.m","chmF2",
|
||||
&gNB->pusch_vars[0]->ul_ch_mag[2][start_symbol*(off+(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_MM("chmagF0.m","chmF3",
|
||||
&gNB->pusch_vars[0]->ul_ch_mag[3][start_symbol*(off+(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_MM("chmagbF0.m","chmbF1",
|
||||
&gNB->pusch_vars[0]->ul_ch_magb[1][start_symbol*(off+(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_MM("chmagbF0.m","chmbF2",
|
||||
&gNB->pusch_vars[0]->ul_ch_magb[2][start_symbol*(off+(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_MM("chmagbF0.m","chmbF3",
|
||||
&gNB->pusch_vars[0]->ul_ch_magb[3][start_symbol*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size))],nb_symb_sch*(off+(NR_NB_SC_PER_RB * pusch_pdu->rb_size)),1,1);
|
||||
if (n_trials==1 && round==0) {
|
||||
LOG_M("rxsig0.m","rx0",&gNB->common_vars.rxdata[0][slot_offset],slot_length,1,1);
|
||||
LOG_M("rxsigF0.m","rxsF0",gNB->common_vars.rxdataF[0],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
if (precod_nbr_layers > 1) {
|
||||
LOG_M("rxsig1.m","rx1",&gNB->common_vars.rxdata[1][slot_offset],slot_length,1,1);
|
||||
LOG_M("rxsigF1.m","rxsF1",gNB->common_vars.rxdataF[1],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
if (precod_nbr_layers==4) {
|
||||
LOG_M("rxsig2.m","rx2",&gNB->common_vars.rxdata[2][slot_offset],slot_length,1,1);
|
||||
LOG_M("rxsig3.m","rx3",&gNB->common_vars.rxdata[3][slot_offset],slot_length,1,1);
|
||||
LOG_M("rxsigF2.m","rxsF2",gNB->common_vars.rxdataF[2],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
LOG_M("rxsigF3.m","rxsF3",gNB->common_vars.rxdataF[3],14*frame_parms->ofdm_symbol_size,1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_M("rxsigF0_llr.m","rxsF0_llr",
|
||||
&gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
if ((gNB->ulsch[0]->last_iteration_cnt >=
|
||||
gNB->ulsch[0]->max_ldpc_iterations+1) || ul_proc_error == 1) {
|
||||
error_flag = 1;
|
||||
n_errors[round][snrRun]++;
|
||||
crc_status = 1;
|
||||
} else {
|
||||
crc_status = 0;
|
||||
}
|
||||
if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);
|
||||
if (n_trials == 1 && round==0) {
|
||||
#ifdef __AVX2__
|
||||
__attribute__((unused))
|
||||
int off = ((nb_rb&1) == 1)? 4:0;
|
||||
#else
|
||||
__attribute__((unused))
|
||||
int off = 0;
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------
|
||||
//----------------- count and print errors -----------------
|
||||
//----------------------------------------------------------
|
||||
LOG_M("rxsigF0_ext.m","rxsF0_ext",
|
||||
&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);
|
||||
LOG_M("rxsigF0_comp.m","rxsF0_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[0][start_symbol*(off+(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("chmagF0.m","chmF0",
|
||||
&gNB->pusch_vars[0]->ul_ch_mag[0][start_symbol*(off+(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("chmagbF0.m","chmbF0",
|
||||
&gNB->pusch_vars[0]->ul_ch_magb[0][start_symbol*(off+(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("rxsigF0_llrlayers0.m","rxsF0_llrlayers0",
|
||||
&gNB->pusch_vars[0]->llr_layers[0][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
|
||||
if (precod_nbr_layers==2) {
|
||||
LOG_M("rxsigF1_ext.m","rxsF1_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[1][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("chestF3.m","chF3",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates[3][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
|
||||
LOG_M("chestF3_ext.m","chF3_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[3][(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);
|
||||
|
||||
LOG_M("rxsigF2_comp.m","rxsF2_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[2][start_symbol*(off+(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("rxsigF0_llrlayers1.m","rxsF0_llrlayers1",
|
||||
&gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
|
||||
if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
|
||||
ptrs_symbols = 0;
|
||||
for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++){
|
||||
ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1;
|
||||
}
|
||||
/* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
|
||||
available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
|
||||
printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) );
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
if(((ulsch_ue->harq_processes[harq_pid]->f[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
|
||||
((ulsch_ue->harq_processes[harq_pid]->f[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0)))
|
||||
{
|
||||
/*if(errors_scrambling == 0)
|
||||
printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/
|
||||
errors_scrambling[round][snrRun]++;
|
||||
}
|
||||
}
|
||||
round++;
|
||||
if (precod_nbr_layers==4) {
|
||||
LOG_M("rxsigF1_ext.m","rxsF1_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[1][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("rxsigF2_ext.m","rxsF2_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[2][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("rxsigF3_ext.m","rxsF3_ext",
|
||||
&gNB->pusch_vars[0]->rxdataF_ext[3][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("chestF5.m","chF5",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates[5][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
LOG_M("chestF10.m","chF10",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates[10][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
LOG_M("chestF15.m","chF15",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates[15][start_symbol*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
|
||||
|
||||
|
||||
LOG_M("chestF5_ext.m","chF5_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[5][(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);
|
||||
LOG_M("chestF10_ext.m","chF10_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[10][(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);
|
||||
LOG_M("chestF15_ext.m","chF15_ext",
|
||||
&gNB->pusch_vars[0]->ul_ch_estimates_ext[15][(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);
|
||||
|
||||
|
||||
LOG_M("rxsigF4_comp.m","rxsF4_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[4][start_symbol*(off+(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("rxsigF8_comp.m","rxsF8_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[8][start_symbol*(off+(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("rxsigF12_comp.m","rxsF12_comp",
|
||||
&gNB->pusch_vars[0]->rxdataF_comp[12][start_symbol*(off+(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("rxsigF0_llrlayers1.m","rxsF0_llrlayers1",
|
||||
&gNB->pusch_vars[0]->llr_layers[1][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
LOG_M("rxsigF0_llrlayers2.m","rxsF0_llrlayers2",
|
||||
&gNB->pusch_vars[0]->llr_layers[2][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
LOG_M("rxsigF0_llrlayers3.m","rxsF0_llrlayers3",
|
||||
&gNB->pusch_vars[0]->llr_layers[3][0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
}
|
||||
|
||||
LOG_M("rxsigF0_llr.m","rxsF0_llr",
|
||||
&gNB->pusch_vars[0]->llr[0],precod_nbr_layers*(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
|
||||
}
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
if ((gNB->ulsch[0]->last_iteration_cnt >=
|
||||
gNB->ulsch[0]->max_ldpc_iterations+1) || ul_proc_error == 1) {
|
||||
error_flag = 1;
|
||||
n_errors[round][snrRun]++;
|
||||
crc_status = 1;
|
||||
} else
|
||||
crc_status = 0;
|
||||
if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);
|
||||
|
||||
//----------------------------------------------------------
|
||||
//----------------- count and print errors -----------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
|
||||
ptrs_symbols = 0;
|
||||
for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++)
|
||||
ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1;
|
||||
|
||||
/* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
|
||||
available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
|
||||
printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) );
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
|
||||
if(((ulsch_ue->harq_processes[harq_pid]->f[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
|
||||
((ulsch_ue->harq_processes[harq_pid]->f[i] == 1) && (gNB->pusch_vars[UE_id]->llr[i] >= 0))) {
|
||||
|
||||
/*if(errors_scrambling == 0)
|
||||
printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/
|
||||
errors_scrambling[round][snrRun]++;
|
||||
}
|
||||
}
|
||||
round++;
|
||||
|
||||
} // round
|
||||
|
||||
@@ -1514,7 +1596,7 @@ int main(int argc, char **argv)
|
||||
if(n_trials==1)
|
||||
break;
|
||||
|
||||
if ((float)n_errors[0][snrRun]/(float)n_trials <= target_error_rate) {
|
||||
if (effRate[snrRun] > (eff_tp_check*TBS)) {
|
||||
printf("*************\n");
|
||||
printf("PUSCH test OK\n");
|
||||
printf("*************\n");
|
||||
|
||||
Reference in New Issue
Block a user