smallblocktest.c 4.6 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
28
29
30
31
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
#include "SIMULATION/TOOLS/sim.h"
#include <getopt.h>

//#define DEBUG_SMALLBLOCKTEST

signed char quantize(double D, double x, unsigned char B)
{
	double qxd;
	short maxlev;
	qxd = floor(x/D);

	maxlev = 1<<(B-1);//(char)(pow(2,B-1));

	if (qxd <= -maxlev)
		qxd = -maxlev;
	else if (qxd >= maxlev)
		qxd = maxlev-1;

	return((char)qxd);
}

int main(int argc, char *argv[]) {

	time_stats_t timeEncoder,timeDecoder;
	opp_enabled=1;
	cpu_freq_GHz = get_cpu_freq_GHz();
	reset_meas(&timeEncoder);
	reset_meas(&timeDecoder);
	randominit(0);

32
33
	int arguments, iterations = 1000, messageLength = 11;
	//int matlabDebug = 0;
34
35
36
37
38
	uint32_t testInput, encoderOutput, codingDifference, nBitError=0, blockErrorState = 0, blockErrorCumulative=0, bitErrorCumulative=0;
	uint16_t estimatedOutput;
	double SNRstart = -20.0, SNRstop = 5.0, SNRinc= 0.5; //dB
	double SNR, SNR_lin, sigma;
	double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS];
39
	//int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS];
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
	int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS];
	unsigned char qbits=8;

	while ((arguments = getopt (argc, argv, "s:d:f:l:i:mhg")) != -1)
	switch (arguments)
	{
		case 's':
			SNRstart = atof(optarg);
			break;

		case 'd':
			SNRinc = atof(optarg);
			break;

		case 'f':
			SNRstop = atof(optarg);
			break;

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

		case 'i':
			iterations = atoi(optarg);
			break;

66
		/*case 'm':
67
68
			matlabDebug = 1;
			//#define DEBUG_POLAR_MATLAB
69
			break;*/
70
71
72
73
74
75
76
77
78

		case 'g':
			iterations = 1;
			SNRstart = -6.0;
			SNRstop = -6.0;
			messageLength = 11;
			break;

		case 'h':
79
80
			//printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations -m Matlab Debug\n");
			printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n");
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
			exit(-1);

		default:
			perror("[smallblocktest.c] Problem at argument parsing with getopt");
			exit(-1);
	}


	uint16_t mask = 0x07ff >> (11-messageLength);
	for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
		printf("SNR %f\n",SNR);
		SNR_lin = pow(10, SNR/10.0);
		sigma = 1.0/sqrt(SNR_lin);

		for (int itr = 1; itr <= iterations; itr++) {

			//Generate random test input of length "messageLength"
			testInput = 0;
			for (int i = 1; i < messageLength; i++) {
				testInput |= ( ((uint32_t) (rand()%2)) &1);
				testInput<<=1;
				}
			testInput |= ( ((uint32_t) (rand()%2)) &1);
			//Encoding
			start_meas(&timeEncoder);
			encoderOutput = encodeSmallBlock((uint16_t*)&testInput, (uint8_t)messageLength);
			stop_meas(&timeEncoder);

			for (int i=0; i<NR_SMALL_BLOCK_CODED_BITS; i++) {
				//BPSK modulation
				if ((encoderOutput>>i) & 1 ) {
					modulatedInput[i]=-1;
				} else {
					modulatedInput[i]=1;
				}

				//AWGN
				channelOutput[i] = modulatedInput[i] + ( gaussdouble(0.0,1.0) * ( 1/sqrt(SNR_lin) ) );

				//Quantization
				channelOutput_int8[i] = quantize(sigma/16.0, channelOutput[i], qbits);
			}

			//Decoding
			start_meas(&timeDecoder);
			estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength);
			stop_meas(&timeDecoder);

#ifdef DEBUG_SMALLBLOCKTEST
			printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput);
			for (int i=0;i<32;i++)
132
				printf("[smallblocktest] Input[%d] = %d, Output[%d] = %d, codingDifference[%d]=%d, Mask[%d] = %d\n", i, (testInput>>i)&1, i, (estimatedOutput>>i)&1, i, (codingDifference>>i)&1, i, (mask>>i)&1);
133
134
135
136
137
138
139
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
#endif

			//Error Calculation
			estimatedOutput &= mask;
			codingDifference = ((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm.

			for (nBitError = 0; codingDifference; nBitError++)
				codingDifference &= codingDifference - 1;

			blockErrorState = (nBitError > 0) ? 1 : 0;

			blockErrorCumulative+=blockErrorState;
			bitErrorCumulative+=nBitError;

			nBitError = 0; blockErrorState = 0;
		}

		//Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively.
		printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n",
				SNR,
				((double)bitErrorCumulative / (iterations*messageLength)),
				((double)blockErrorCumulative/iterations),
				((double)timeEncoder.diff/timeEncoder.trials)/(cpu_freq_GHz),
				((double)timeDecoder.diff/timeDecoder.trials)/(cpu_freq_GHz*1000.0));

		blockErrorCumulative=0;
		bitErrorCumulative=0;
	}

	print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL);
	print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL);

	return (0);
}