Hide normal table initialization of Ziggurat generator from outside to
force the usage of randominit() for RNG initialization. In this step,
remove the randominit() seed parameter and only rely on OAI_RNGSEED for
a consistent RNG initialization, as this parameter was used differently
("0" as fixed number or to force a random seed).
Now, only use OAI_RNGSEED env variable to force the usage of a fixed
seed.
178 lines
5.6 KiB
C
178 lines
5.6 KiB
C
#include <getopt.h>
|
||
#include "common/config/config_userapi.h"
|
||
#include "SIMULATION/TOOLS/sim.h"
|
||
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||
#include "coding_unitary_defs.h"
|
||
|
||
//#define DEBUG_SMALLBLOCKTEST
|
||
|
||
configmodule_interface_t *uniqCfg = NULL;
|
||
int main(int argc, char *argv[])
|
||
{
|
||
time_stats_t timeEncoder, timeDecoder;
|
||
cpu_meas_enabled = 1;
|
||
reset_meas(&timeEncoder);
|
||
reset_meas(&timeDecoder);
|
||
randominit();
|
||
|
||
int ret = 1;
|
||
int arguments, iterations = 1000, messageLength = 11;
|
||
// int matlabDebug = 0;
|
||
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];
|
||
// int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS];
|
||
int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS];
|
||
unsigned char qbits = 8;
|
||
|
||
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
|
||
exit_fun("[SMALLBLOCKTEST] Error, configuration module init failed\n");
|
||
}
|
||
logInit();
|
||
|
||
while ((arguments = getopt(argc, argv, "--:O:s:d:f:l:i:mhg")) != -1) {
|
||
|
||
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
|
||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||
if (arguments == 1 || arguments == '-' || arguments == 'O')
|
||
continue;
|
||
|
||
printf("handling optarg %c\n",arguments);
|
||
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;
|
||
|
||
/*case 'm':
|
||
matlabDebug = 1;
|
||
//#define DEBUG_POLAR_MATLAB
|
||
break;*/
|
||
|
||
case 'g':
|
||
iterations = 1;
|
||
SNRstart = -6.0;
|
||
SNRstop = -6.0;
|
||
messageLength = 11;
|
||
break;
|
||
|
||
case 'h':
|
||
// 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");
|
||
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) {
|
||
blockErrorCumulative = 0;
|
||
bitErrorCumulative = 0;
|
||
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(testInput, 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++)
|
||
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);
|
||
#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) / (get_cpu_freq_GHz()),
|
||
((double)timeDecoder.diff / timeDecoder.trials) / (get_cpu_freq_GHz() * 1000.0));
|
||
}
|
||
|
||
print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL);
|
||
print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL);
|
||
|
||
if (blockErrorCumulative == 0) {
|
||
ret = 0;
|
||
}
|
||
|
||
return ret;
|
||
}
|