dlschsim.c 18.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 41
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
42
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
43
#include "PHY/NR_TRANSPORT/nr_transport.h"
44
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
45
#include "SCHED_NR/sched_nr.h"
46 47 48 49
#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"
50

51
//#define DEBUG_NR_DLSCHSIM
52

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

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

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

67 68
int main(int argc, char **argv)
{
69 70 71 72 73 74 75 76 77 78
	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;
79
	//uint8_t write_output_file = 0;
80 81 82
	//  int subframe_offset;
	//  char fname[40], vname[40];
	int trial, n_trials = 1, n_errors = 0, n_false_positive = 0;
83 84
	uint8_t n_tx = 1, n_rx = 1;
	//uint8_t transmission_mode = 1;
85 86 87
	uint16_t Nid_cell = 0;
	channel_desc_t *gNB2UE;
	uint8_t extended_prefix_flag = 0;
88
	//int8_t interf1 = -21, interf2 = -21;
89 90 91 92
	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;
93
	uint16_t N_RB_DL = 106, mu = 1;
94
	//unsigned char frame_type = 0;
95
	unsigned char pbch_phase = 0;
96
	int frame = 0, slot = 0;
97 98 99 100 101 102 103 104 105 106 107 108
	int frame_length_complex_samples;
	//int frame_length_complex_samples_no_prefix;
	NR_DL_FRAME_PARMS *frame_parms;
	//nfapi_nr_config_request_t *gNB_config;
	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;
	float target_error_rate = 0.01;
109
        uint64_t SSB_positions=0x01;
110 111 112
	uint16_t nb_symb_sch = 12;
	uint16_t nb_rb = 50;
	uint8_t Imcs = 9;
113
        uint8_t mcs_table = 0;
114 115 116

	cpuf = get_cpu_freq_GHz();

117
	if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) {
yilmazt's avatar
yilmazt committed
118
		exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n");
119 120 121 122 123
	}

	//logInit();
	randominit(0);

124
	while ((c = getopt(argc, argv, "df:hpVg:i:j:n:l:m:r:s:S:y:z:M:N:F:R:P:L:")) != -1) {
125
		switch (c) {
126
		/*case 'f':
127 128 129 130 131 132 133 134
			write_output_file = 1;
			output_fd = fopen(optarg, "w");

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

135
			break;*/
136

137
		/*case 'd':
138
			frame_type = 1;
139
			break;*/
140 141 142 143 144 145 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

		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:
172
				printf("Unsupported channel model! Exiting.\n");
173 174 175 176 177
				exit(-1);
			}

			break;

178
		/*case 'i':
179 180 181 182 183
			interf1 = atoi(optarg);
			break;

		case 'j':
			interf2 = atoi(optarg);
184
			break;*/
185 186 187 188 189 190 191

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

		case 's':
			snr0 = atof(optarg);
192 193 194
#ifdef DEBUG_NR_DLSCHSIM
			printf("Setting SNR0 to %f\n", snr0);
#endif
195 196
			break;

197 198 199 200
		case 'V':
		  ouput_vcd = 1;
		  break;

201 202 203
		case 'S':
			snr1 = atof(optarg);
			snr1set = 1;
204
			printf("Setting SNR1 to %f\n", snr1);
205 206 207
#ifdef DEBUG_NR_DLSCHSIM
			printf("Setting SNR1 to %f\n", snr1);
#endif
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
			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)) {
228
				printf("Unsupported number of TX antennas %d. Exiting.\n", n_tx);
229 230 231 232 233 234 235 236 237
				exit(-1);
			}

			break;

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

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

			break;

244 245 246 247
	        case 'M':
      			SSB_positions = atoi(optarg);
			break;		    

248 249 250 251 252 253 254 255 256 257 258 259
		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) {
260
				printf("Problem with filename %s. Exiting.\n", optarg);
261 262 263 264 265 266 267 268 269 270 271 272 273
				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;

274 275 276 277
		case 'L':
		  loglvl = atoi(optarg);
		  break;

278 279 280 281 282 283 284 285 286 287 288 289
		case 'm':
			Imcs = atoi(optarg);
			break;

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

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

290
		/*case 'x':
291
			transmission_mode = atoi(optarg);
292
			break;*/
293 294 295 296 297 298

		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");
299
			printf("-V Enable VCD dumb functions\n");
300
			//printf("-d Use TDD\n");
301 302 303 304 305
			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");
306
			//printf("-x Transmission mode (1,2,6 for the moment)\n");
307 308
			printf("-y Number of TX antennas used in eNB\n");
			printf("-z Number of RX antennas used in UE\n");
309 310 311
			//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");
312 313 314 315
			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");
316 317
			//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");
318 319 320 321 322 323 324 325 326 327 328 329 330
			printf("-F Input filename (.txt format) for RX conformance testing\n");
			exit(-1);
			break;
		}
	}

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

	if (snr1set == 0)
		snr1 = snr0 + 10;

331 332 333
	if (ouput_vcd)
        vcd_signal_dumper_init("/tmp/openair_dump_nr_dlschsim.vcd");

334 335 336 337
	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),
				      0, 0, 0);
338 339

	if (gNB2UE == NULL) {
340
		printf("Problem generating channel model. Exiting.\n");
341 342 343 344 345 346 347 348 349 350 351 352
		exit(-1);
	}

	RC.gNB = (PHY_VARS_gNB ** *) malloc(sizeof(PHY_VARS_gNB **));
	RC.gNB[0] = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
	RC.gNB[0][0] = malloc(sizeof(PHY_VARS_gNB));
	gNB = RC.gNB[0][0];
	//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;
353
	frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL;
354
	crcTableInit();
355
	nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions);
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
	phy_init_nr_gNB(gNB, 0, 0);
	//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
376
		bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 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
	}

	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];
	NR_gNB_DLSCH_t *dlsch = gNB->dlsch[0][0];
	nfapi_nr_dl_config_dlsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
	//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;
	uint8_t nb_re_dmrs = 6;
	uint16_t length_dmrs = 1;
	unsigned char mod_order;
434
        uint16_t rate;
435 436 437 438 439 440 441
	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);
442 443
	mod_order = nr_get_Qm_dl(Imcs, mcs_table);
        rate = nr_get_code_rate_dl(Imcs, mcs_table);
444
	available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1);
445
	TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl);
yilmazt's avatar
yilmazt committed
446
	printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order);
447 448 449 450 451 452 453
	//dlsch->harq_ids[subframe]= 0;
	rel15->n_prb = nb_rb;
	rel15->nb_symbols = nb_symb_sch;
	rel15->modulation_order = mod_order;
	rel15->nb_layers = Nl;
	rel15->nb_re_dmrs = nb_re_dmrs;
	rel15->transport_block_size = TBS;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
454
  rel15->coding_rate = rate;
Ahmed's avatar
Ahmed committed
455
	double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
456 457 458
	short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
	short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
	double errors_bit_uncoded = 0;
459
	//unsigned char *estimated_output;
460 461
	unsigned char *estimated_output_bit;
	unsigned char *test_input_bit;
462 463
	unsigned int errors_bit = 0;
	test_input_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
464
	//estimated_output = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
465
	estimated_output_bit = (unsigned char *) malloc16(sizeof(unsigned char) * 16 * 68 * 384);
466
	NR_UE_DLSCH_t *dlsch0_ue = UE->dlsch[0][0][0];
467 468
	NR_DL_UE_HARQ_t *harq_process = dlsch0_ue->harq_processes[harq_pid];
	harq_process->mcs = Imcs;
469
	harq_process->mcs_table = mcs_table;
470 471 472 473
	harq_process->Nl = Nl;
	harq_process->nb_rb = nb_rb;
	harq_process->Qm = mod_order;
	harq_process->rvidx = rvidx;
474
	harq_process->R = rate;
475 476 477 478 479 480 481
	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();

482
	//estimated_output = harq_process->b;
483

484
#ifdef DEBUG_NR_DLSCHSIM
yilmazt's avatar
yilmazt committed
485
	for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]);
486 487 488 489 490 491 492 493
#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
	if (input_fd == NULL) {
494
		nr_dlsch_encoding(test_input, frame, slot, dlsch, frame_parms);
495
	}
496

497 498 499
	for (SNR = snr0; SNR < snr1; SNR += snr_step) {
		n_errors = 0;
		n_false_positive = 0;
500

501 502 503 504 505 506
		for (trial = 0; trial < n_trials; trial++) {
			errors_bit_uncoded = 0;
			for (i = 0; i < available_bits; i++) {
#ifdef DEBUG_CODER
				if ((i&0xf)==0)
				printf("\ne %d..%d:    ",i,i+15);
507 508
#endif

509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
				//if (i<16)
				//   printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]);
				if (dlsch->harq_processes[0]->f[i] == 0)
					modulated_input[i] = 1.0;        ///sqrt(2);  //QPSK
				else
					modulated_input[i] = -1.0;        ///sqrt(2);

				//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);

				//if (i<16)   printf("channel_output_fixed[%d] = %d\n",i,channel_output_fixed[i]);

				//Uncoded BER
				if (channel_output_fixed[i] < 0)
					channel_output_uncoded[i] = 1;  //QPSK demod
				else
					channel_output_uncoded[i] = 0;

				if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i])
					errors_bit_uncoded = errors_bit_uncoded + 1;
			}

			//if (errors_bit_uncoded>10)
			//printf("errors bits uncoded %f\n", errors_bit_uncoded);
543
#ifdef DEBUG_CODER
544 545
			printf("\n");
			exit(-1);
546
#endif
547 548 549

			vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN);

550 551
			ret = nr_dlsch_decoding(UE, channel_output_fixed, &UE->frame_parms,
					dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch,
552
					slot,harq_pid, is_crnti, llr8_flag);
553

554 555
			vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_OUT);

556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
			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
575
					printf("errors_bit %u (trial %d)\n", errors_bit, trial);
576 577 578 579 580 581 582
			}
		}

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

583 584 585 586
		if ((float) n_errors / (float) n_trials < target_error_rate) {
		  printf("PDSCH test OK\n");
		  break;
		}
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
	}

	/*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);
		free_gNB_dlsch(gNB->dlsch[0][i]);
		printf("UE %d\n", i);
626
		free_nr_ue_dlsch(UE->dlsch[0][0][i]);
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
	}

	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);

649 650 651
	if (ouput_vcd)
        vcd_signal_dumper_close();

652
	return (n_errors);
653 654
}