dlschsim.c 19.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

#include <string.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
28
#include "common/ran_context.h"
29 30
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
31
#include "common/utils/LOG/vcd_signal_dumper.h"
32
#include "T.h"
33
#include "PHY/defs_gNB.h"
34 35
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
36
#include "PHY/types.h"
37
#include "PHY/INIT/phy_init.h"
38 39
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
40
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
41
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
cig's avatar
cig committed
42
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
43
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
44
#include "SCHED_NR/sched_nr.h"
45 46 47 48
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
49

50
//#define DEBUG_NR_DLSCHSIM
51

52 53 54
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
55
UE_nr_rxtx_proc_t proc;
56 57
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];

58
double cpuf;
59
//uint8_t nfapi_mode = 0;
yilmazt's avatar
yilmazt committed
60
uint16_t NB_UE_INST = 1;
61

62 63
uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
64

65
// needed for some functions
66 67
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234;
68
openair0_config_t openair0_cfg[MAX_CARDS];
69

70 71
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}

72 73
int main(int argc, char **argv)
{
74 75 76 77 78 79 80 81 82 83
	char c;
	int i; //,j,l,aa;
	double SNR, SNR_lin, snr0 = -2.0, snr1 = 2.0;
	double snr_step = 0.1;
	uint8_t snr1set = 0;
	int **txdata;
	double **s_re, **s_im, **r_re, **r_im;
	//  int sync_pos, sync_pos_slot;
	//  FILE *rx_frame_file;
	FILE *output_fd = NULL;
84
	//uint8_t write_output_file = 0;
85 86 87
	//  int subframe_offset;
	//  char fname[40], vname[40];
	int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
88 89
	uint8_t n_tx = 1, n_rx = 1;
	//uint8_t transmission_mode = 1;
90 91 92
	uint16_t Nid_cell = 0;
	channel_desc_t *gNB2UE;
	uint8_t extended_prefix_flag = 0;
93
	//int8_t interf1 = -21, interf2 = -21;
94 95 96 97
	FILE *input_fd = NULL, *pbch_file_fd = NULL;
	//char input_val_str[50],input_val_str2[50];
	//uint16_t NB_RB=25;
	SCM_t channel_model = AWGN;  //Rayleigh1_anticorr;
98
	uint16_t N_RB_DL = 106, mu = 1; 
99
	//unsigned char frame_type = 0;
100
	unsigned char pbch_phase = 0;
101
	int frame = 0, slot = 0;
102 103 104 105 106 107 108 109 110 111
	int frame_length_complex_samples;
	//int frame_length_complex_samples_no_prefix;
	NR_DL_FRAME_PARMS *frame_parms;
	uint8_t Kmimo = 0;
	uint32_t Nsoft = 0;
	double sigma;
	unsigned char qbits = 8;
	int ret;
	//int run_initial_sync=0;
	int loglvl = OAILOG_WARNING;
112
	uint8_t dlsch_threads = 0;
113
	float target_error_rate = 0.01;
114
        uint64_t SSB_positions=0x01;
115 116 117
	uint16_t nb_symb_sch = 12;
	uint16_t nb_rb = 50;
	uint8_t Imcs = 9;
118
        uint8_t mcs_table = 0;
119
        double DS_TDL = .03;
120
	cpuf = get_cpu_freq_GHz();
Raymond Knopp's avatar
Raymond Knopp committed
121 122
	char gNBthreads[128]="n";
	
123
	if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
yilmazt's avatar
yilmazt committed
124
		exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n");
125 126 127 128 129
	}

	//logInit();
	randominit(0);

Raymond Knopp's avatar
Raymond Knopp committed
130
	while ((c = getopt(argc, argv, "df:hpVg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:L:X:")) != -1) {
131
		switch (c) {
132
		/*case 'f':
133 134 135 136 137 138 139 140
			write_output_file = 1;
			output_fd = fopen(optarg, "w");

			if (output_fd == NULL) {
				printf("Error opening %s\n", optarg);
				exit(-1);
			}

141
			break;*/
142

143 144 145
		case 'd':
			dlsch_threads = atoi(optarg);
			break;
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177

		case 'g':
			switch ((char) *optarg) {
			case 'A':
				channel_model = SCM_A;
				break;

			case 'B':
				channel_model = SCM_B;
				break;

			case 'C':
				channel_model = SCM_C;
				break;

			case 'D':
				channel_model = SCM_D;
				break;

			case 'E':
				channel_model = EPA;
				break;

			case 'F':
				channel_model = EVA;
				break;

			case 'G':
				channel_model = ETU;
				break;

			default:
178
				printf("Unsupported channel model! Exiting.\n");
179 180 181 182 183
				exit(-1);
			}

			break;

184
		/*case 'i':
185 186 187 188 189
			interf1 = atoi(optarg);
			break;

		case 'j':
			interf2 = atoi(optarg);
190
			break;*/
191 192 193 194 195 196 197

		case 'n':
			n_trials = atoi(optarg);
			break;

		case 's':
			snr0 = atof(optarg);
198 199 200
#ifdef DEBUG_NR_DLSCHSIM
			printf("Setting SNR0 to %f\n", snr0);
#endif
201 202
			break;

203 204 205 206
		case 'V':
		  ouput_vcd = 1;
		  break;

207 208 209
		case 'S':
			snr1 = atof(optarg);
			snr1set = 1;
210
			printf("Setting SNR1 to %f\n", snr1);
211 212 213
#ifdef DEBUG_NR_DLSCHSIM
			printf("Setting SNR1 to %f\n", snr1);
#endif
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
			break;

		case 'p':
			extended_prefix_flag = 1;
			break;

			/*
			 case 'r':
			 ricean_factor = pow(10,-.1*atof(optarg));
			 if (ricean_factor>1) {
			 printf("Ricean factor must be between 0 and 1\n");
			 exit(-1);
			 }
			 break;
			 */

		case 'y':
			n_tx = atoi(optarg);

			if ((n_tx == 0) || (n_tx > 2)) {
234
				printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx);
235 236 237 238 239 240 241 242 243
				exit(-1);
			}

			break;

		case 'z':
			n_rx = atoi(optarg);

			if ((n_rx == 0) || (n_rx > 2)) {
244
				printf("Unsupported number of RX antennas %d. Exiting.\n", n_rx);
245 246 247 248 249
				exit(-1);
			}

			break;

250 251 252 253
	        case 'M':
      			SSB_positions = atoi(optarg);
			break;		    

254 255 256 257 258 259 260 261 262 263 264 265
		case 'N':
			Nid_cell = atoi(optarg);
			break;

		case 'R':
			N_RB_DL = atoi(optarg);
			break;

		case 'F':
			input_fd = fopen(optarg, "r");

			if (input_fd == NULL) {
266
				printf("Problem with filename %s. Exiting.\n", optarg);
267 268 269 270 271 272 273 274 275 276 277 278 279
				exit(-1);
			}

			break;

		case 'P':
			pbch_phase = atoi(optarg);

			if (pbch_phase > 3)
				printf("Illegal PBCH phase (0-3) got %d\n", pbch_phase);

			break;

280 281 282 283
		case 'L':
		  loglvl = atoi(optarg);
		  break;

284 285 286 287 288 289 290 291 292 293 294 295
		case 'm':
			Imcs = atoi(optarg);
			break;

		case 'l':
			nb_symb_sch = atoi(optarg);
			break;

		case 'r':
			nb_rb = atoi(optarg);
			break;

Raymond Knopp's avatar
Raymond Knopp committed
296 297 298 299 300
		case 'X':
		  strncpy(gNBthreads, optarg, sizeof(gNBthreads));
		  gNBthreads[sizeof(gNBthreads)-1]=0;
		  break;

301
		/*case 'x':
302
			transmission_mode = atoi(optarg);
303
			break;*/
304 305 306 307 308 309

		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", argv[0]);
			printf("-h This message\n");
			printf("-p Use extended prefix mode\n");
310
			printf("-V Enable VCD dumb functions\n");
311
			//printf("-d Use TDD\n");
312 313 314 315 316
			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("-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");
317
			//printf("-x Transmission mode (1,2,6 for the moment)\n");
318 319
			printf("-y Number of TX antennas used in eNB\n");
			printf("-z Number of RX antennas used in UE\n");
320 321 322
			//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("-M Multiple SSB positions in burst\n");
323 324 325 326
			printf("-N Nid_cell\n");
			printf("-R N_RB_DL\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");
327 328
			//printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
			//printf("-f Output filename (.txt format) for Pe/SNR results\n");
329
			printf("-F Input filename (.txt format) for RX conformance testing\n");
330
			printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
331 332 333 334 335 336 337 338 339 340 341
			exit(-1);
			break;
		}
	}

	logInit();
	set_glog(loglvl);
	T_stdout = 1;

	if (snr1set == 0)
		snr1 = snr0 + 10;
342
	init_dlsch_tpool(dlsch_threads);
343

344 345 346
	if (ouput_vcd)
        vcd_signal_dumper_init("/tmp/openair_dump_nr_dlschsim.vcd");

347 348 349
	gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, 
				      61.44e6, //N_RB2sampling_rate(N_RB_DL),
				      40e6, //N_RB2channel_bandwidth(N_RB_DL),
350
                                      DS_TDL,
351
				      0, 0, 0, 0);
352 353

	if (gNB2UE == NULL) {
354
		printf("Problem generating channel model. Exiting.\n");
355 356 357
		exit(-1);
	}

358 359 360
	RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
	RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
	gNB = RC.gNB[0];
Raymond Knopp's avatar
Raymond Knopp committed
361 362
	gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
	initTpool(gNBthreads, gNB->threadPool, true);
363 364 365 366 367
	//gNB_config = &gNB->gNB_config;
	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;
368
	frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
369
	crcTableInit();
370
	nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions);
371
	phy_init_nr_gNB(gNB, 0, 1); //lowmem
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
	//init_eNB_afterRU();
	frame_length_complex_samples = frame_parms->samples_per_subframe;
	//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP;
	s_re = malloc(2 * sizeof(double *));
	s_im = malloc(2 * sizeof(double *));
	r_re = malloc(2 * sizeof(double *));
	r_im = malloc(2 * sizeof(double *));
	txdata = malloc(2 * sizeof(int *));

	for (i = 0; i < 2; i++) {
		s_re[i] = malloc(frame_length_complex_samples * sizeof(double));
		bzero(s_re[i], frame_length_complex_samples * sizeof(double));
		s_im[i] = malloc(frame_length_complex_samples * sizeof(double));
		bzero(s_im[i], frame_length_complex_samples * sizeof(double));
		r_re[i] = malloc(frame_length_complex_samples * sizeof(double));
		bzero(r_re[i], frame_length_complex_samples * sizeof(double));
		r_im[i] = malloc(frame_length_complex_samples * sizeof(double));
		bzero(r_im[i], frame_length_complex_samples * sizeof(double));
		txdata[i] = malloc(frame_length_complex_samples * sizeof(int));
Ahmed's avatar
Ahmed committed
391
		bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
	}

	if (pbch_file_fd != NULL) {
		load_pbch_desc(pbch_file_fd);
	}

	/*  for (int k=0; k<2; k++) {
	 // Create transport channel structures for 2 transport blocks (MIMO)
	 for (i=0; i<2; i++) {
	 gNB->dlsch[k][i] = new_gNB_dlsch(Kmimo,8,Nsoft,0,frame_parms,gNB_config);

	 if (!gNB->dlsch[k][i]) {
	 printf("Can't get eNB dlsch structures\n");
	 exit(-1);
	 }
	 gNB->dlsch[k][i]->Nsoft = 10;
	 gNB->dlsch[k][i]->rnti = n_rnti+k;
	 }
	 }*/
	//configure UE
	UE = malloc(sizeof(PHY_VARS_NR_UE));
	memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS));

	//phy_init_nr_top(frame_parms);
	if (init_nr_ue_signal(UE, 1, 0) != 0) {
		printf("Error at UE NR initialisation\n");
		exit(-1);
	}

	//nr_init_frame_parms_ue(&UE->frame_parms);
	//init_nr_ue_transport(UE, 0);
	for (int sf = 0; sf < 2; sf++) {
		for (i = 0; i < 2; i++) {
			UE->dlsch[sf][0][i] = new_nr_ue_dlsch(Kmimo, 8, Nsoft, 5, N_RB_DL,
					0);

			if (!UE->dlsch[sf][0][i]) {
				printf("Can't get ue dlsch structures\n");
				exit(-1);
			}

			UE->dlsch[sf][0][i]->rnti = n_rnti;
		}
	}

	UE->dlsch_SI[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
	UE->dlsch_ra[0] = new_nr_ue_dlsch(1, 1, Nsoft, 5, N_RB_DL, 0);
	unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
Sakthivel Velumani's avatar
Sakthivel Velumani committed
440 441 442
  processingData_L1tx_t msgDataTx;
  init_DLSCH_struct(gNB, &msgDataTx);
	NR_gNB_DLSCH_t *dlsch = msgDataTx.dlsch[0][0];
443
	nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
444 445 446 447
	//time_stats_t *rm_stats, *te_stats, *i_stats;
	uint8_t is_crnti = 0, llr8_flag = 0;
	unsigned int TBS = 8424;
	unsigned int available_bits;
Francesco Mani's avatar
Francesco Mani committed
448
	uint8_t nb_re_dmrs = 6;  // No data in dmrs symbol
449 450
	uint16_t length_dmrs = 1;
	unsigned char mod_order;
451
        uint16_t rate;
452 453 454 455 456 457 458
	uint8_t Nl = 1;
	uint8_t rvidx = 0;
	dlsch->rnti = 1;
	/*dlsch->harq_processes[0]->mcs = Imcs;
	 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);
459 460
	mod_order = nr_get_Qm_dl(Imcs, mcs_table);
        rate = nr_get_code_rate_dl(Imcs, mcs_table);
461
	available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
462
	TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl);
yilmazt's avatar
yilmazt committed
463
	printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
464
	//dlsch->harq_ids[subframe]= 0;
465 466 467 468
	rel15->rbSize         = nb_rb;
	rel15->NrOfSymbols    = nb_symb_sch;
	rel15->qamModOrder[0] = mod_order;
	rel15->nrOfLayers     = Nl;
469
	rel15->TBSize[0]      = TBS>>3;
470 471
        rel15->targetCodeRate[0] = rate;
        rel15->NrOfCodewords = 1;
472
        rel15->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
473
	rel15->dlDmrsSymbPos = 4;
474
	rel15->mcsIndex[0] = Imcs;
Francesco Mani's avatar
Francesco Mani committed
475
        rel15->numDmrsCdmGrpsNoData = 1;
Ahmed's avatar
Ahmed committed
476
	double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
477 478
	short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
	short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
479
	//unsigned char *estimated_output;
480 481
	unsigned char *estimated_output_bit;
	unsigned char *test_input_bit;
482 483
	unsigned int errors_bit = 0;
	test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
484
	//estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
485
	estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
486
	NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0];
487 488
	NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
	harq_process->mcs = Imcs;
489
	harq_process->mcs_table = mcs_table;
490 491 492 493
	harq_process->Nl = Nl;
	harq_process->nb_rb = nb_rb;
	harq_process->Qm = mod_order;
	harq_process->rvidx = rvidx;
494
	harq_process->R = rate;
495
	harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1;
496
	harq_process->dlDmrsSymbPos = 4;
497
	harq_process->n_dmrs_cdm_groups = 1;
498 499 500 501 502 503 504
	printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
	unsigned char *test_input;
	test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);

	for (i = 0; i < TBS / 8; i++)
		test_input[i] = (unsigned char) rand();

505
	//estimated_output = harq_process->b;
506

507
#ifdef DEBUG_NR_DLSCHSIM
yilmazt's avatar
yilmazt committed
508
	for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]);
509 510 511 512 513 514 515
#endif

	/*for (int i=0; i<TBS/8; i++)
	 printf("test input[%d]=%d \n",i,test_input[i]);*/

	//printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32));
	// generate signal
516 517
	    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);
518
	if (input_fd == NULL) {
519
	  nr_dlsch_encoding(gNB, test_input, frame, slot, dlsch, frame_parms,output,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
520
	}
521

522 523 524
	for (SNR = snr0; SNR < snr1; SNR += snr_step) {
		n_errors = 0;
		n_false_positive = 0;
525

526 527 528 529 530
		for (trial = 0; trial < n_trials; trial++) {
			for (i = 0; i < available_bits; i++) {
#ifdef DEBUG_CODER
				if ((i&0xf)==0)
				printf("\ne %d..%d:    ",i,i+15);
531 532
#endif

533 534
				//if (i<16)
				//   printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
Raymond Knopp's avatar
Raymond Knopp committed
535 536
				
				if (output[i] == 0)
537 538 539
					modulated_input[i] = 1.0;        ///sqrt(2);  //QPSK
				else
					modulated_input[i] = -1.0;        ///sqrt(2);
Raymond Knopp's avatar
Raymond Knopp committed
540
				
541 542 543 544 545 546 547 548 549 550 551 552
				//if (i<16) printf("modulated_input[%d] = %d\n",i,modulated_input[i]);
				//SNR =10;
				SNR_lin = pow(10, SNR / 10.0);
				sigma = 1.0 / sqrt(2 * SNR_lin);
				channel_output_fixed[i] = (short) quantize(sigma / 4.0 / 4.0,
						modulated_input[i] + sigma * gaussdouble(0.0, 1.0),
						qbits);
				//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
				//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
				//printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);

				//channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);
553 554 555 556 557
/*
				if (i<16)   printf("input[%d] %f => channel_output_fixed[%d] = %d\n",
						   i,modulated_input[i],
						   i,channel_output_fixed[i]);
*/
Raymond Knopp's avatar
Raymond Knopp committed
558

559 560 561 562 563 564 565
				//Uncoded BER
				if (channel_output_fixed[i] < 0)
					channel_output_uncoded[i] = 1;  //QPSK demod
				else
					channel_output_uncoded[i] = 0;
			}

566
#ifdef DEBUG_CODER
567 568
			printf("\n");
			exit(-1);
569
#endif
570 571 572

			vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN);

573
			ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms,
574
					dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch,
575
					slot,harq_pid, is_crnti, llr8_flag);
576

577 578
			vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT);

579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
			if (ret > dlsch0_ue->max_ldpc_iterations)
				n_errors++;

			//count errors
			errors_bit = 0;

			for (i = 0; i < TBS; i++) {
				estimated_output_bit[i] = (dlsch0_ue->harq_processes[0]->b[i / 8] & (1 << (i & 7))) >> (i & 7);
				test_input_bit[i] = (test_input[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments

				if (estimated_output_bit[i] != test_input_bit[i]) {
					errors_bit++;
					//printf("estimated bits error occurs @%d ",i);
				}
			}

			if (errors_bit > 0) {
				n_false_positive++;
				if (n_trials == 1)
yilmazt's avatar
yilmazt committed
598
					printf("errors_bit %u (trial %d)\n", errors_bit, trial);
599 600 601 602 603 604 605
			}
		}

		printf("SNR %f, BLER %f (false positive %f)\n", SNR,
				(float) n_errors / (float) n_trials,
				(float) n_false_positive / (float) n_trials);

606 607 608 609
		if ((float) n_errors / (float) n_trials < target_error_rate) {
		  printf("PDSCH test OK\n");
		  break;
		}
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
	}

	/*LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
	 if (gNB->frame_parms.nb_antennas_tx>1)
	 LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);*/

	//TODO: loop over slots
	/*for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
	 if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) {
	 PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
	 txdata[aa],
	 frame_parms->ofdm_symbol_size,
	 12,
	 frame_parms->nb_prefix_samples,
	 CYCLIC_PREFIX);
	 } else {
	 nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
	 txdata[aa],
	 14,
	 frame_parms);
	 }
	 }

	 LOG_M("txsig0.m","txs0", txdata[0],frame_length_complex_samples,1,1);
	 if (gNB->frame_parms.nb_antennas_tx>1)
	 LOG_M("txsig1.m","txs1", txdata[1],frame_length_complex_samples,1,1);


	 for (i=0; i<frame_length_complex_samples; i++) {
	 for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
	 r_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
	 r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
	 }
	 }*/

	for (i = 0; i < 2; i++) {
		printf("gNB %d\n", i);
Sakthivel Velumani's avatar
Sakthivel Velumani committed
647
		free_gNB_dlsch(&(msgDataTx.dlsch[0][i]),N_RB_DL);
648
		printf("UE %d\n", i);
649
		free_nr_ue_dlsch(&(UE->dlsch[0][0][i]),N_RB_DL);
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
	}

	for (i = 0; i < 2; i++) {
		free(s_re[i]);
		free(s_im[i]);
		free(r_re[i]);
		free(r_im[i]);
		free(txdata[i]);
	}

	free(s_re);
	free(s_im);
	free(r_re);
	free(r_im);
	free(txdata);

	if (output_fd)
		fclose(output_fd);

	if (input_fd)
		fclose(input_fd);

672 673 674
	if (ouput_vcd)
        vcd_signal_dumper_close();

675
	return (n_errors);
676 677
}