Merge remote-tracking branch 'origin/improve-pucch-codec' into integration_2024_w01
This commit is contained in:
@@ -8,144 +8,152 @@
|
|||||||
configmodule_interface_t *uniqCfg = NULL;
|
configmodule_interface_t *uniqCfg = NULL;
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
time_stats_t timeEncoder,timeDecoder;
|
time_stats_t timeEncoder, timeDecoder;
|
||||||
opp_enabled=1;
|
opp_enabled = 1;
|
||||||
reset_meas(&timeEncoder);
|
reset_meas(&timeEncoder);
|
||||||
reset_meas(&timeDecoder);
|
reset_meas(&timeDecoder);
|
||||||
randominit(0);
|
randominit(0);
|
||||||
|
|
||||||
int arguments, iterations = 1000, messageLength = 11;
|
int arguments, iterations = 1000, messageLength = 11;
|
||||||
//int matlabDebug = 0;
|
// int matlabDebug = 0;
|
||||||
uint32_t testInput, encoderOutput, codingDifference, nBitError=0, blockErrorState = 0, blockErrorCumulative=0, bitErrorCumulative=0;
|
uint32_t testInput, encoderOutput, codingDifference, nBitError = 0, blockErrorState = 0, blockErrorCumulative = 0,
|
||||||
uint16_t estimatedOutput;
|
bitErrorCumulative = 0;
|
||||||
double SNRstart = -20.0, SNRstop = 5.0, SNRinc= 0.5; //dB
|
uint16_t estimatedOutput;
|
||||||
double SNR, SNR_lin, sigma;
|
double SNRstart = -20.0, SNRstop = 5.0, SNRinc = 0.5; // dB
|
||||||
double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS];
|
double SNR, SNR_lin, sigma;
|
||||||
//int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS];
|
double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS];
|
||||||
int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS];
|
// int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS];
|
||||||
unsigned char qbits=8;
|
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)
|
while ((arguments = getopt(argc, argv, "s:d:f:l:i:mhg")) != -1)
|
||||||
switch (arguments)
|
switch (arguments) {
|
||||||
{
|
case 's':
|
||||||
case 's':
|
SNRstart = atof(optarg);
|
||||||
SNRstart = atof(optarg);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
SNRinc = atof(optarg);
|
SNRinc = atof(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
SNRstop = atof(optarg);
|
SNRstop = atof(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
messageLength = atoi(optarg);
|
messageLength = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
iterations = atoi(optarg);
|
iterations = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*case 'm':
|
/*case 'm':
|
||||||
matlabDebug = 1;
|
matlabDebug = 1;
|
||||||
//#define DEBUG_POLAR_MATLAB
|
//#define DEBUG_POLAR_MATLAB
|
||||||
break;*/
|
break;*/
|
||||||
|
|
||||||
case 'g':
|
case 'g':
|
||||||
iterations = 1;
|
iterations = 1;
|
||||||
SNRstart = -6.0;
|
SNRstart = -6.0;
|
||||||
SNRstop = -6.0;
|
SNRstop = -6.0;
|
||||||
messageLength = 11;
|
messageLength = 11;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
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 -m Matlab Debug\n");
|
||||||
printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n");
|
printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
perror("[smallblocktest.c] Problem at argument parsing with getopt");
|
perror("[smallblocktest.c] Problem at argument parsing with getopt");
|
||||||
exit(-1);
|
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);
|
||||||
|
|
||||||
uint16_t mask = 0x07ff >> (11-messageLength);
|
for (int itr = 1; itr <= iterations; itr++) {
|
||||||
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
|
// Generate random test input of length "messageLength"
|
||||||
printf("SNR %f\n",SNR);
|
testInput = 0;
|
||||||
SNR_lin = pow(10, SNR/10.0);
|
for (int i = 1; i < messageLength; i++) {
|
||||||
sigma = 1.0/sqrt(SNR_lin);
|
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 itr = 1; itr <= iterations; itr++) {
|
for (int i = 0; i < NR_SMALL_BLOCK_CODED_BITS; i++) {
|
||||||
|
// BPSK modulation
|
||||||
|
if ((encoderOutput >> i) & 1) {
|
||||||
|
modulatedInput[i] = -1;
|
||||||
|
} else {
|
||||||
|
modulatedInput[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
//Generate random test input of length "messageLength"
|
// AWGN
|
||||||
testInput = 0;
|
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0, 1.0) * (1 / sqrt(SNR_lin)));
|
||||||
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++) {
|
// Quantization
|
||||||
//BPSK modulation
|
channelOutput_int8[i] = quantize(sigma / 16.0, channelOutput[i], qbits);
|
||||||
if ((encoderOutput>>i) & 1 ) {
|
}
|
||||||
modulatedInput[i]=-1;
|
|
||||||
} else {
|
|
||||||
modulatedInput[i]=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//AWGN
|
// Decoding
|
||||||
channelOutput[i] = modulatedInput[i] + ( gaussdouble(0.0,1.0) * ( 1/sqrt(SNR_lin) ) );
|
start_meas(&timeDecoder);
|
||||||
|
estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength);
|
||||||
//Quantization
|
stop_meas(&timeDecoder);
|
||||||
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
|
#ifdef DEBUG_SMALLBLOCKTEST
|
||||||
printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput);
|
printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput);
|
||||||
for (int i=0;i<32;i++)
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
//Error Calculation
|
// Error Calculation
|
||||||
estimatedOutput &= mask;
|
estimatedOutput &= mask;
|
||||||
codingDifference = ((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm.
|
codingDifference =
|
||||||
|
((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm.
|
||||||
|
|
||||||
for (nBitError = 0; codingDifference; nBitError++)
|
for (nBitError = 0; codingDifference; nBitError++)
|
||||||
codingDifference &= codingDifference - 1;
|
codingDifference &= codingDifference - 1;
|
||||||
|
|
||||||
blockErrorState = (nBitError > 0) ? 1 : 0;
|
blockErrorState = (nBitError > 0) ? 1 : 0;
|
||||||
|
|
||||||
blockErrorCumulative+=blockErrorState;
|
blockErrorCumulative += blockErrorState;
|
||||||
bitErrorCumulative+=nBitError;
|
bitErrorCumulative += nBitError;
|
||||||
|
|
||||||
nBitError = 0; blockErrorState = 0;
|
nBitError = 0;
|
||||||
}
|
blockErrorState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively.
|
// 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",
|
printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n",
|
||||||
SNR,
|
SNR,
|
||||||
((double)bitErrorCumulative / (iterations*messageLength)),
|
((double)bitErrorCumulative / (iterations * messageLength)),
|
||||||
((double)blockErrorCumulative/iterations),
|
((double)blockErrorCumulative / iterations),
|
||||||
((double)timeEncoder.diff/timeEncoder.trials)/(get_cpu_freq_GHz()),
|
((double)timeEncoder.diff / timeEncoder.trials) / (get_cpu_freq_GHz()),
|
||||||
((double)timeDecoder.diff/timeDecoder.trials)/(get_cpu_freq_GHz()*1000.0));
|
((double)timeDecoder.diff / timeDecoder.trials) / (get_cpu_freq_GHz() * 1000.0));
|
||||||
|
|
||||||
blockErrorCumulative=0;
|
blockErrorCumulative = 0;
|
||||||
bitErrorCumulative=0;
|
bitErrorCumulative = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL);
|
print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL);
|
||||||
print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL);
|
print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,12 @@
|
|||||||
|
|
||||||
//input = [0 ... 0 c_K-1 ... c_2 c_1 c_0]
|
//input = [0 ... 0 c_K-1 ... c_2 c_1 c_0]
|
||||||
//output = [d_31 d_30 ... d_2 d_1 d_0]
|
//output = [d_31 d_30 ... d_2 d_1 d_0]
|
||||||
uint32_t encodeSmallBlock(uint16_t *in, uint8_t len){
|
uint32_t encodeSmallBlock(int in, int len)
|
||||||
uint32_t out = 0;
|
{
|
||||||
for (uint16_t i=0; i<len; i++)
|
uint32_t out = 0;
|
||||||
if ((*in & (1<<i)) > 0)
|
for (int i = 0; i < len; i++)
|
||||||
out^=nrSmallBlockBasis[i];
|
if ((in & (1 << i)) > 0)
|
||||||
|
out ^= nrSmallBlockBasis[i];
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#define L1d_CLS 64
|
#define L1d_CLS 64
|
||||||
|
|
||||||
uint32_t encodeSmallBlock(uint16_t *in, uint8_t len);
|
uint32_t encodeSmallBlock(int in, int len);
|
||||||
|
|
||||||
uint16_t decodeSmallBlock(int8_t *in, uint8_t len);
|
uint16_t decodeSmallBlock(int8_t *in, uint8_t len);
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
||||||
uint32_t n_id,
|
uint32_t n_id,
|
||||||
uint8_t n_hop,
|
int n_hop,
|
||||||
int nr_slot_tx,
|
int nr_slot_tx,
|
||||||
uint8_t *u,
|
uint8_t *u,
|
||||||
uint8_t *v);
|
uint8_t *v);
|
||||||
|
|||||||
@@ -32,12 +32,13 @@
|
|||||||
|
|
||||||
#include "nr_dci.h"
|
#include "nr_dci.h"
|
||||||
|
|
||||||
void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping,
|
void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping,
|
||||||
uint32_t n_id,
|
uint32_t n_id,
|
||||||
uint8_t n_hop,
|
int n_hop,
|
||||||
int nr_slot_tx,
|
int nr_slot_tx,
|
||||||
uint8_t *u,
|
uint8_t *u,
|
||||||
uint8_t *v) {
|
uint8_t *v)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping
|
* Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping
|
||||||
* The following variables are set by higher layers:
|
* The following variables are set by higher layers:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -215,7 +215,8 @@ extern "C" {
|
|||||||
{
|
{
|
||||||
return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)};
|
return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)};
|
||||||
}
|
}
|
||||||
__attribute__((always_inline)) inline c16_t c16divShift(const c16_t a, const c16_t b, const int Shift) {
|
__attribute__((always_inline)) inline c16_t c16MulConjShift(const c16_t a, const c16_t b, const int Shift)
|
||||||
|
{
|
||||||
return (c16_t) {
|
return (c16_t) {
|
||||||
.r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift),
|
.r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift),
|
||||||
.i = (int16_t)((a.r * b.i - a.i * b.r) >> Shift)
|
.i = (int16_t)((a.r * b.i - a.i * b.r) >> Shift)
|
||||||
|
|||||||
@@ -83,64 +83,7 @@ binary_search_float_nr(
|
|||||||
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void nr_generate_pucch0(int32_t **txdataF,
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
|
||||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
|
||||||
int16_t amp,
|
|
||||||
int nr_slot_tx,
|
|
||||||
uint8_t mcs,
|
|
||||||
uint8_t nrofSymbols,
|
|
||||||
uint8_t startingSymbolIndex,
|
|
||||||
uint16_t startingPRB);
|
|
||||||
|
|
||||||
void nr_generate_pucch1(int32_t **txdataF,
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
|
||||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
|
||||||
uint64_t payload,
|
|
||||||
int16_t amp,
|
|
||||||
int nr_slot_tx,
|
|
||||||
uint8_t nrofSymbols,
|
|
||||||
uint8_t startingSymbolIndex,
|
|
||||||
uint16_t startingPRB,
|
|
||||||
uint16_t startingPRB_intraSlotHopping,
|
|
||||||
uint8_t timeDomainOCC,
|
|
||||||
uint8_t nr_bit);
|
|
||||||
|
|
||||||
void nr_generate_pucch2(int32_t **txdataF,
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
|
||||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
|
||||||
uint64_t payload,
|
|
||||||
int16_t amp,
|
|
||||||
int nr_slot_tx,
|
|
||||||
uint8_t nrofSymbols,
|
|
||||||
uint8_t startingSymbolIndex,
|
|
||||||
uint8_t nrofPRB,
|
|
||||||
uint16_t startingPRB,
|
|
||||||
uint8_t nr_bit);
|
|
||||||
|
|
||||||
void nr_generate_pucch3_4(int32_t **txdataF,
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
|
||||||
pucch_format_nr_t fmt,
|
|
||||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
|
||||||
uint64_t payload,
|
|
||||||
int16_t amp,
|
|
||||||
int nr_slot_tx,
|
|
||||||
uint8_t nrofSymbols,
|
|
||||||
uint8_t startingSymbolIndex,
|
|
||||||
uint8_t nrofPRB,
|
|
||||||
uint16_t startingPRB,
|
|
||||||
uint8_t nr_bit,
|
|
||||||
uint8_t occ_length_format4,
|
|
||||||
uint8_t occ_index_format4);
|
|
||||||
*/
|
|
||||||
/**************** variables **************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/**************** functions **************************************/
|
|
||||||
|
|
||||||
//extern uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
|
|
||||||
//extern uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
*
|
*
|
||||||
* NAME : pucch_procedures_ue_nr
|
* NAME : pucch_procedures_ue_nr
|
||||||
|
|||||||
Reference in New Issue
Block a user