Commit 80060d9e authored by Raymond Knopp's avatar Raymond Knopp

Merge remote-tracking branch 'origin/polar-decoder-optimizations' into nr_pbchsim

parents 874c165f ffc5faf3
......@@ -1125,6 +1125,7 @@ set(PHY_POLARSRC
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c
# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c
# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/decoder_K56_N512_E864.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c
${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c
......
......@@ -15,12 +15,23 @@ int main(int argc, char *argv[]) {
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder;
time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving;
time_stats_t path_metric,sorting,update_LLR;
opp_enabled=1;
int decoder_int8=0;
cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
randominit(0);
reset_meas(&polar_decoder_init);
reset_meas(&polar_rate_matching);
reset_meas(&decoding);
reset_meas(&bit_extraction);
reset_meas(&deinterleaving);
reset_meas(&sorting);
reset_meas(&path_metric);
reset_meas(&update_LLR);
randominit(1234);
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 1; //0=DCI, 1=PBCH, 2=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
......@@ -32,8 +43,9 @@ int main(int argc, char *argv[]) {
double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint8_t decoderListSize = 8, pathMetricAppr = 0; //0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12)
int generate_optim_code=0;
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h")) != -1)
while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:qg")) != -1)
switch (arguments)
{
case 's':
......@@ -65,6 +77,17 @@ int main(int argc, char *argv[]) {
pathMetricAppr = (uint8_t) atoi(optarg);
break;
case 'q':
decoder_int8=1;
break;
case 'g':
generate_optim_code=1;
iterations=1;
SNRstart=-6.0;
SNRstop =-6.0;
decoder_int8=1;
break;
case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
exit(-1);
......@@ -121,16 +144,23 @@ int main(int argc, char *argv[]) {
double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input
double *channelOutput = malloc (sizeof(double) * coderLength); //add noise
int16_t *channelOutput_int8 = malloc (sizeof(int16_t) * coderLength); //add noise
uint8_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output
t_nrPolar_params nrPolar_params;
nr_polar_init(&nrPolar_params, polarMessageType);
nr_polar_llrtableinit();
if (generate_optim_code==1) nrPolar_params.decoder_kernel = NULL;
// We assume no a priori knowledge available about the payload.
double aPrioriArray[nrPolar_params.payloadBits];
for (int i=0; i<nrPolar_params.payloadBits; i++) aPrioriArray[i] = NAN;
for (int i=0; i<=nrPolar_params.payloadBits; i++) aPrioriArray[i] = NAN;
printf("SNRstart %f, SNRstop %f,, SNRinc %f\n",SNRstart,SNRstop,SNRinc);
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10);
for (itr = 1; itr <= iterations; itr++) {
......@@ -149,13 +179,29 @@ int main(int argc, char *argv[]) {
modulatedInput[i]=(-1)/sqrt(2);
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int8==1) {
if (channelOutput[i] > 15) channelOutput_int8[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int8[i] = -128;
else channelOutput_int8[i] = (int16_t) (8*channelOutput[i]);
}
}
start_meas(&timeDecoder);
decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr);
stop_meas(&timeDecoder);
if (decoder_int8==0)
decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params,
decoderListSize, aPrioriArray, pathMetricAppr,
&polar_decoder_init,&polar_rate_matching,&decoding,
&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR);
else
decoderState = polar_decoder_int8_new(channelOutput_int8, estimatedOutput, &nrPolar_params,
decoderListSize, &polar_decoder_init,&polar_rate_matching,
&decoding,&bit_extraction,&deinterleaving,
&sorting,&path_metric,&update_LLR,
generate_optim_code);
stop_meas(&timeDecoder);
//calculate errors
if (decoderState==-1) {
blockErrorState=-1;
......@@ -191,7 +237,15 @@ int main(int argc, char *argv[]) {
decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations),
((double)bitErrorCumulative / (iterations*testLength)),
(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
printf("decoding init %9.3fus\n",polar_decoder_init.diff/(cpu_freq_GHz*1000.0*polar_decoder_init.trials));
printf("decoding polar_rate_matching %9.3fus\n",polar_rate_matching.diff/(cpu_freq_GHz*1000.0*polar_rate_matching.trials));
printf("decoding decoding %9.3fus\n",decoding.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding bit_extraction %9.3fus\n",bit_extraction.diff/(cpu_freq_GHz*1000.0*bit_extraction.trials));
printf("decoding deinterleaving %9.3fus\n",deinterleaving.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials));
printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*decoding.trials));
printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*decoding.trials));
blockErrorCumulative = 0; bitErrorCumulative = 0;
timeEncoderCumulative = 0; timeDecoderCumulative = 0;
}
......
......@@ -27,9 +27,9 @@ void nr_polar_init(t_nrPolar_params* polarParams, int messageType) {
uint32_t poly6 = 0x84000000; // 1000100000... -> D^6+D^5+1
uint32_t poly11 = 0x63200000; //11000100001000... -> D^11+D^10+D^9+D^5+1
uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1
uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1
uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1
//uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1
//uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1
//uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1
uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
if (messageType == 0) { //DCI
......@@ -62,6 +62,11 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat
polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat
polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat
polarParams->decoder_kernel = NULL;//polar_decoder_K56_N512_E864;
} else if (messageType == 2) { //UCI
polarParams->payloadBits = NR_POLAR_PUCCH_PAYLOAD_BITS; //A depends on what they carry...
polarParams->encoderLength = NR_POLAR_PUCCH_E ; //E depends on other standards 6.3.1.4
......@@ -131,6 +136,7 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat
polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat
polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat
}
polarParams->crcCorrectionBits = NR_POLAR_CRC_ERROR_CORRECTION_BITS;
......@@ -161,5 +167,38 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
nr_polar_channel_interleaver_pattern(polarParams->channel_interleaver_pattern,
polarParams->i_bil, polarParams->encoderLength);
polarParams->extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t tempECGM[polarParams->K][polarParams->crcParityBits];
for (int i = 0; i < polarParams->K; i++){
polarParams->extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
}
}
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
if( (i-polarParams->payloadBits) == j ){
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
}
}
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
polarParams->extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
}
}
build_decoder_tree(polarParams);
printf("decoder tree nodes %d\n",polarParams->tree.num_nodes);
free(J);
}
......@@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* For more information about the OpenAirInterface (OAI) Software Alliance
* contact@openairinterface.org
*/
......@@ -27,6 +27,8 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/TOOLS/time_meas.h"
int8_t polar_decoder(
double *input,
......@@ -34,242 +36,502 @@ int8_t polar_decoder(
t_nrPolar_params *polarParams,
uint8_t listSize,
double *aPrioriPayload,
uint8_t pathMetricAppr)
uint8_t pathMetricAppr,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR)
{
uint8_t ***bit = nr_alloc_uint8_t_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize);
uint8_t **crcChecksum = nr_alloc_uint8_t_2D_array(polarParams->crcParityBits, 2*listSize);
double *pathMetric = malloc(sizeof(double)*(2*listSize));
uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True
start_meas(init);
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
for (int i = 0; i < polarParams->K; i++){
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
}
for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
}
}
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
if( (i-polarParams->payloadBits) == j ){
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
}
}
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
}
}
uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
decoder_list_t dlist[2*listSize];
for ( int i=0;i<2*listSize;i++) {
// dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
// dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N);
//dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits);
for (int j=0; j< polarParams->n+1; j++) {
memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N);
memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N);
}
for (int j=0;j<polarParams->crcParityBits;j++) dlist[i].crcChecksum[j] = 0;
dlist[i].pathMetric = 0;
}
for (int i=0; i<polarParams->N; i++) {
memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
stop_meas(init);
start_meas(polar_rate_matching);
double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N);
stop_meas(polar_rate_matching);
/*
* SCL polar decoder.
*/
start_meas(decoding);
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
decoder_list_t *sorted_dlist[2*listSize];
decoder_list_t *temp_dlist[2*listSize];
int listIndex[2*listSize];
double pathMetric[2*listSize];
for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i];
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
// printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n",
// currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]);
start_meas(update_LLR);
updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
stop_meas(update_LLR);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
//Information bit with known value of "0".
updatePathMetric(sorted_dlist, currentListSize, 0, currentBit, pathMetricAppr);
bitUpdated[currentBit][0]=1; //0=False, 1=True
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
//Information bit with known value of "1".
printf("Information bit with known value of 1\n");
updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr);
for (uint8_t i=0; i<currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
} else {
start_meas(path_metric);
updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr);
stop_meas(path_metric);
start_meas(sorting);
for (int i=0; i<(2*listSize); i++) {
pathMetric[i] = 0;
crcState[i]=1;
}
for (int i=0; i<polarParams->N; i++) {
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3
uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2
for (int i = 0; i < polarParams->K; i++){
extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t));
if (currentListSize <= listSize/2) {
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
for (int i = 0; i < currentListSize; i++) {
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N);
}
}
}
for (int i=0; i<polarParams->payloadBits; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
tempECGM[i][j]=polarParams->crc_generator_matrix[i][j];
}
}
for (int i=polarParams->payloadBits; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
if( (i-polarParams->payloadBits) == j ){
tempECGM[i][j]=1;
} else {
tempECGM[i][j]=0;
}
}
}
for (int i=0; i<polarParams->K; i++) {
for (int j=0; j<polarParams->crcParityBits; j++) {
extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j];
}
for (int i = 0; i < currentListSize; i++) {
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;
}
bitUpdated[currentBit][0]=1;
updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
int listIndex2[listSize];
for (int i = 0; i < currentListSize; i++) {
listIndex[i]=i;
pathMetric[i] = sorted_dlist[i]->pathMetric;
}
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
for (int i=0;i<currentListSize;i++) {
listIndex2[listIndex[i]] = i;
}
//The index of the last 1-valued bit that appears in each column.
uint16_t last1ind[polarParams->crcParityBits];
for (int j=0; j<polarParams->crcParityBits; j++) {
for (int i=0; i<polarParams->K; i++) {
if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i;
}
// copy the llr/bit arrays that are needed
for (int i = 0; i < listSize; i++) {
if ((listIndex2[i+listSize]<listSize) && (listIndex2[i]<listSize)) { // both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(double)*polarParams->N);
}
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
}
else if (listIndex2[i+listSize]<listSize) { // only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(double)*polarParams->N);
}
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
currentListSize = listSize;
for (int i = 0; i < 2*listSize; i++) {
temp_dlist[i] = sorted_dlist[i];
}
for (int i = 0; i < 2*listSize; i++) {
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist[i] = temp_dlist[listIndex[i]];
}
}
stop_meas(sorting);
}
nonFrozenBit++;
}
}
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
// printf("list index %d :",i);
// for (int j=0;j<polarParams->crcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]);
// printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric);
int crcState = 1;
for (int j=0;j<polarParams->crcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0;
if (crcState == 1) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j];
start_meas(bit_extraction);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
stop_meas(bit_extraction);
//Deinterleaving (ĉ to b)
start_meas(deinterleaving);
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
stop_meas(deinterleaving);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
break;
}
}
// free(d_tilde);
/*
for (int i=0;i<2*listSize;i++) {
// printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit);
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
free(dlist[i].crcChecksum);
}*/
nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_t_2D_array(tempECGM, polarParams->K);
stop_meas(decoding);
return(0);
}
double *d_tilde = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
for (int j = 0; j < polarParams->N; j++) llr[j][polarParams->n][0]=d_tilde[j];
/*
* SCL polar decoder.
*/
int8_t polar_decoder_int8(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR,
int generate_optim_code)
{
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
uint8_t decoderIterationCheck=0;
int16_t checkCrcBits=-1;
uint8_t listIndex[2*listSize], copyIndex;
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) {
//Information bit with known value of "0".
updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr);
bitUpdated[currentBit][0]=1; //0=False, 1=True
} else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) {
//Information bit with known value of "1".
updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr);
for (uint8_t i=0; i<currentListSize; i++) bit[currentBit][0][i]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
} else {
updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr);
uint8_t **bitUpdated;
uint8_t **llrUpdated;
for (int i = 0; i < currentListSize; i++) {
for (int j = 0; j < polarParams->N; j++) {
for (int k = 0; k < (polarParams->n+1); k++) {
bit[j][k][i+currentListSize]=bit[j][k][i];
llr[j][k][i+currentListSize]=llr[j][k][i];}}}
for (int i = 0; i < currentListSize; i++) {
bit[currentBit][0][i]=0;
crcState[i+currentListSize]=crcState[i];
}
for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1;
bitUpdated[currentBit][0]=1;
updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits);
currentListSize*=2;
if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) {
bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True
}
decoder_list_int8_t dlist[2*listSize];
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
//sort listIndex[listSize, ..., 2*listSize-1] in descending order.
uint8_t swaps, tempInd;
for (uint8_t i = 0; i < listSize; i++) {
swaps = 0;
for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) {
if (listIndex[j+1] > listIndex[j]) {
tempInd = listIndex[j];
listIndex[j] = listIndex[j + 1];
listIndex[j + 1] = tempInd;
swaps++;
}
}
if (swaps == 0)
break;
}
start_meas(init);
for ( int i=0;i<2*listSize;i++) {
// dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N);
// dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N);
//dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits);
for (int j=0; j< polarParams->n+1; j++) {
memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N);
memset((void*)&dlist[i].llr[j][0],0,sizeof(int16_t)*polarParams->N);
}
for (int j=0;j<polarParams->crcParityBits;j++) dlist[i].crcChecksum[j] = 0;
dlist[i].pathMetric = 0;
}
//First, backup the best "listSize" number of entries.
for (int k=(listSize-1); k>0; k--) {
for (int i=0; i<polarParams->N; i++) {
for (int j=0; j<(polarParams->n+1); j++) {
bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]];
llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]];
}
}
}
for (int k=(listSize-1); k>0; k--) {
for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]];
}
}
for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]];
stop_meas(init);
if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) {
for (int i=0; i<polarParams->N; i++) {
memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n);
llrUpdated[i][polarParams->n]=1;
bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2);
}
}
//Copy the best "listSize" number of entries to the first indices.
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
for (int i = 0; i < polarParams->N; i++) {
for (int j = 0; j < (polarParams->n + 1); j++) {
bit[i][j][k] = bit[i][j][copyIndex];
llr[i][j][k] = llr[i][j][copyIndex];
}
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
for (int i = 0; i < polarParams->crcParityBits; i++) {
crcChecksum[i][k]=crcChecksum[i][copyIndex];
}
}
for (int k = 0; k < listSize; k++) {
if (k > listIndex[k]) {
copyIndex = listIndex[(2*listSize-1)-k];
} else { //Use the backup.
copyIndex = listIndex[k];
}
crcState[k]=crcState[copyIndex];
}
currentListSize = listSize;
}
}
start_meas(polar_rate_matching);
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
for (int i=0;i<polarParams->N;i++) {
if (d_tilde[i]<-128) d_tilde[i]=-128;
else if (d_tilde[i]>127) d_tilde[i]=128;
}
memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N);
stop_meas(polar_rate_matching);
/*
* SCL polar decoder.
*/
start_meas(decoding);
uint32_t nonFrozenBit=0;
uint8_t currentListSize=1;
decoder_list_int8_t *sorted_dlist[2*listSize];
for (int i=0; i<polarParams->crcParityBits; i++) {
if (last1ind[i]==nonFrozenBit) {
checkCrcBits=i;
break;
}
}
for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i];
char fname[100];
FILE *fd;
if (generate_optim_code==1) {
sprintf(fname,"decoder_K%d_N%d_E%d.c",polarParams->K,polarParams->N,polarParams->encoderLength);
if ((fd=fopen(fname,"w"))==NULL) {printf("Cannot open %s\n",fname); exit(-1);}
fprintf(fd,"#include \"nr_polar_defs.h\"\n");
fprintf(fd,"void polar_decoder_K%d_N%d_E%d(t_nrPolar_params *polarParams,decoder_list_int8_t **sorted_dlist) {\n",
polarParams->K,polarParams->N,polarParams->encoderLength);
fprintf(fd,"int16_t mask,absllr;\n");
}
if ( checkCrcBits > (-1) ) {
for (uint8_t i = 0; i < currentListSize; i++) {
if (crcChecksum[checkCrcBits][i]==1) {
crcState[i]=0; //0=False, 1=True
}
}
}
if (polarParams->decoder_kernel) polarParams->decoder_kernel(polarParams,sorted_dlist);
else {
for (uint16_t currentBit=0; currentBit<polarParams->N; currentBit++){
printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n",
currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]);
start_meas(update_LLR);
updateLLR_int8(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1),generate_optim_code,fd);
stop_meas(update_LLR);
if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit.
updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit,generate_optim_code,fd); //approximation=0 --> 11b, approximation=1 --> 12
} else { //Information or CRC bit.
start_meas(path_metric);
updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit,generate_optim_code,fd);
stop_meas(path_metric);
start_meas(sorting);
if (currentListSize <= listSize/2) {
// until listsize is full we need to copy bit and LLR arrays to new entries
// below we only copy the ones we need to keep for sure
decoder_int8_A(sorted_dlist,currentListSize,polarParams);
if (generate_optim_code == 1) fprintf(fd,"decoder_int8_A(sorted_dlist,%d,polarParams);\n",currentListSize);
}
decoder_int8_B(sorted_dlist,currentBit,currentListSize);
if (generate_optim_code == 1) fprintf(fd,"decoder_int8_B(sorted_dlist,%d,%d);\n",currentBit,currentListSize);
bitUpdated[currentBit][0]=1;
updateCrcChecksum2_int8(sorted_dlist,polarParams->extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits,generate_optim_code,fd);
currentListSize*=2;
//Keep only the best "listSize" number of entries.
if (currentListSize > listSize) {
decoder_int8_C(sorted_dlist,
polarParams,
currentBit,
currentListSize,
listSize);
if (generate_optim_code == 1) fprintf(fd,"decoder_int8_C(sorted_dlist,polarParams,%d,%d,%d);\n",currentBit,currentListSize,listSize);
currentListSize = listSize;
}
stop_meas(sorting);
nonFrozenBit++;
}
}
}
for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i];
if (decoderIterationCheck==0) {
//perror("[SCL polar decoder] All list entries have failed the CRC checks.");
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits);
return(-1);
}
if (generate_optim_code==1) fprintf(fd,"}\n");
nonFrozenBit++;
decoderIterationCheck=0;
checkCrcBits=-1;
}
}
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
// printf("list index %d / %d :",i,listSize);
// for (int j=0;j<polarParams->crcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]);
// printf(" => (%d)\n",sorted_dlist[i]->pathMetric);
int crcState = 1;
for (int j=0;j<polarParams->crcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0;
if (crcState == 1) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j];
start_meas(bit_extraction);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
stop_meas(bit_extraction);
//Deinterleaving (ĉ to b)
start_meas(deinterleaving);
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
stop_meas(deinterleaving);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
break;
}
}
// free(d_tilde);
/*
for (int i=0;i<2*listSize;i++) {
// printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit);
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
free(dlist[i].crcChecksum);
}*/
stop_meas(decoding);
return(0);
}
for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i;
nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize);
for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) {
if ( crcState[listIndex[i]] == 1 ) {
for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[j][0][listIndex[i]];
int8_t polar_decoder_int8_new(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR,
int generate_optim_code)
{
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
start_meas(init);
stop_meas(init);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
start_meas(polar_rate_matching);
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
for (int i=0;i<polarParams->N;i++) {
if (d_tilde[i]<-128) d_tilde[i]=-128;
else if (d_tilde[i]>127) d_tilde[i]=128;
}
memcpy((void*)&polarParams->tree.root->alpha[0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N);
stop_meas(polar_rate_matching);
/*
* SCL polar decoder.
*/
start_meas(decoding);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
generic_polar_decoder(polarParams,polarParams->tree.root);
break;
}
}
start_meas(bit_extraction);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N);
stop_meas(bit_extraction);
//Deinterleaving (ĉ to b)
start_meas(deinterleaving);
nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K);
stop_meas(deinterleaving);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j];
free(d_tilde);
free(pathMetric);
free(crcState);
nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1));
nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1));
nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits);
nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K);
nr_free_uint8_t_2D_array(tempECGM, polarParams->K);
return(0);
// free(d_tilde);
/*
for (int i=0;i<2*listSize;i++) {
// printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit);
nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1));
nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1));
free(dlist[i].crcChecksum);
}*/
stop_meas(decoding);
return(0);
}
......@@ -19,118 +19,519 @@
* contact@openairinterface.org
*/
#include "PHY/impl_defs_top.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/sse_intrin.h"
void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) {
uint16_t offset = (xlen/(pow(2,(ylen-col-1))));
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen);
if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i];
} else {
if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
computeLLR(llr, row, col, i, offset, approximation);
}
inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
uint16_t offset, uint8_t approximation) __attribute__((always_inline));
inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col,
uint16_t offset, uint8_t approximation) {
double a;
double b;
double absA,absB;
a = llr[col + 1][row];
b = llr[col+1][row + offset];
if (approximation) { //eq. (9)
absA = fabs(a);
absB = fabs(b);
llr[col][row] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
} else { //eq. (8a)
llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
int16_t llrtab[256][256];
llrU[row][col]=1;
void nr_polar_llrtableinit() {
int16_t absA,absB;
int16_t minabs;
for (int a=-128;a<128;a++) {
for (int b=-128;b<128;b++) {
absA=abs(a);
absB=abs(b);
minabs = absA<absB ? absA:absB;
if ((a<0 && b<0) || (a>=0 && b>=0)) llrtab[a+128][b+128] = minabs;
else llrtab[a+128][b+128] = -minabs;
}
}
}
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen) {
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
bit[row][col][i] = bit[row][col-1][i];
} else {
if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen);
bit[row][col][i] = ( (bit[row][col-1][i]+bit[row+offset][col-1][i]) % 2);
}
}
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) {
bitU[row][col]=1;
uint16_t offset = (xlen/(1<<(ylen-col-1)));
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen);
if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation);
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
for (uint8_t i=0; i<listSize; i++) {
dlist[i]->llr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row];
}
} else {
if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation);
if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation);
for (int i=0;i<listSize;i++) computeLLR(dlist[i]->llr, row, col, offset, approximation);
}
llrU[row][col]=1;
}
void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation) {
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen,
int generate_optim_code,FILE *fd) {
uint16_t offset = (xlen/(1<<(ylen-col-1)));
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen,generate_optim_code,fd);
if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen,generate_optim_code,fd);
if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd);
if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,llr[row][0][i]) )) pathMetric[i] += fabs(llr[row][0][i]);
}
} else { //eq. (11b)
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) pathMetric[i] += log ( 1 + exp(multiplier*llr[row][0][i]) ) ;
}
if (generate_optim_code==1) fprintf(fd,"updateLLR_int8_A(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset);
updateLLR_int8_A(dlist,listSize,col,row,offset);
} else {
if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd);
if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen,generate_optim_code,fd);
if (generate_optim_code==1) fprintf(fd,"computeLLR_int8(sorted_dlist,%d,%d,%d,%d);\n",listSize,row,col,offset);
computeLLR_int8(dlist,listSize, row, col, offset);
}
llrU[row][col]=1;
}
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint16_t row, uint8_t appr) {
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen) {
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
} else {
if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen);
if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen);
dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2);
}
}
bitU[row][col]=1;
}
double *tempPM = malloc(sizeof(double) * listSize);
for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i];
uint8_t bitValue = 0;
if (appr) { //eq. (12)
for (uint8_t i = 0; i < listSize; i++) {
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][i]))) pathMetric[i] += fabs(llr[row][0][i]);
}
} else { //eq. (11b)
int8_t multiplier = (2 * bitValue) - 1;
for (uint8_t i = 0; i < listSize; i++) pathMetric[i] += log(1 + exp(multiplier * llr[row][0][i]));
}
bitValue = 1;
if (appr) { //eq. (12)
for (uint8_t i = listSize; i < 2*listSize; i++) {
if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][(i-listSize)]))) pathMetric[i] = tempPM[(i-listSize)] + fabs(llr[row][0][(i-listSize)]);
}
} else { //eq. (11b)
int8_t multiplier = (2 * bitValue) - 1;
for (uint8_t i = listSize; i < 2*listSize; i++) pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)]));
}
void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU,
uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen,
int generate_optim_code,FILE *fd) {
free(tempPM);
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
if (( (row) % (2*offset) ) >= offset ) {
if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row];
if (generate_optim_code==1) fprintf(fd,"updateBit_int8_A(sorted_dlist,%d,%d,%d);\n",listSize,col,row);
updateBit_int8_A(dlist,listSize,col,row);
} else {
if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd);
if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen,generate_optim_code,fd);
// dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset];
// printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]);
if (generate_optim_code==1) fprintf(fd,"updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset);
updateBit_int8_B(dlist,listSize,col,row,offset);
}
bitU[row][col]=1;
}
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation) {
if (approximation) { //eq. (12)
for (uint8_t i=0; i<listSize; i++) {
if ((2*bitValue) != ( 1 - copysign(1.0,dlist[i]->llr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]);
}
} else { //eq. (11b)
int8_t multiplier = (2*bitValue) - 1;
for (uint8_t i=0; i<listSize; i++) {
dlist[i]->pathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ;
}
}
}
void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i,
uint16_t offset, uint8_t approximation) {
double a = llr[row][col + 1][i];
double absA = fabs(a);
double b = llr[row + offset][col + 1][i];
double absB = fabs(b);
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) {
if (approximation || isinf(absA) || isinf(absB)) { //eq. (9)
llr[row][col][i] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB);
} else { //eq. (8a)
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
int16_t mask,absllr;
updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr);
if (generate_optim_code == 1) fprintf(fd,"updatePathMetric0_int8_A(sorted_dlist,%d,%d,mask,absllr);\n",listSize,row);
/*
mask = dlist[i]->llr[0][row]>>15;
if (mask != 0) {
int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask;
dlist[i]->pathMetric += absllr;
}*/
}
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) {
int i;
for (i=0;i<listSize;i++) dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
decoder_list_t **dlist2 = &dlist[listSize];
if (appr) { //eq. (12)
for (i = 0; i < listSize; i++) {
// bitValue=0
if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
// bitValue=1
else dlist2[i]->pathMetric += dlist[i]->llr[0][row];
}
} else { //eq. (11b)
for (i = 0; i < listSize; i++) {
// bitValue=0
dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row]));
// bitValue=1
dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row]));
}
}
}
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) {
if (generate_optim_code == 1) fprintf(fd,"updatePathMetric2_int8_A(sorted_dlist,%d,%d);\n",
listSize,row);
updatePathMetric2_int8_A(dlist,listSize,row);
// dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;
//if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row];
//else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];
}
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
}
}
}
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) {
if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);\n",listSize,i2,len);
updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) {
if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum2_int8_A(sorted_dlist,%d,polarParams->extended_crc_generator_matrix,%d,%d);\n",listSize,i2,len);
updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len);
// for (uint8_t j = 0; j < len; j++) {
// dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 );
// }
}
decoder_node_t *new_decoder_node(int first_leaf_index,int level) {
decoder_node_t *node=(decoder_node_t *)malloc(sizeof(decoder_node_t));
node->first_leaf_index=first_leaf_index;
node->level=level;
node->Nv = 1<<level;
node->leaf = 0;
node->left=(decoder_node_t *)NULL;
node->right=(decoder_node_t *)NULL;
node->all_frozen=0;
node->alpha = (int16_t*)malloc16(node->Nv*sizeof(int16_t));
node->beta = (int16_t*)malloc16(node->Nv*sizeof(int16_t));
memset((void*)node->beta,-1,node->Nv*sizeof(int16_t));
return(node);
}
decoder_node_t *add_nodes(int level,int first_leaf_index,t_nrPolar_params *pp) {
int all_frozen_below=1;
int Nv = 1<<level;
decoder_node_t *new_node = new_decoder_node(first_leaf_index,level);
#ifdef DEBUG_NEW_IMPL
printf("New node %d order %d, level %d\n",pp->tree.num_nodes,Nv,level);
pp->tree.num_nodes++;
#endif
if (level==0) {
#ifdef DEBUG_NEW_IMPL
printf("leaf %d (%s)\n",first_leaf_index,pp->information_bit_pattern[first_leaf_index]==1 ? "information or crc" : "frozen");
#endif
new_node->leaf=1;
new_node->all_frozen = pp->information_bit_pattern[first_leaf_index]==0 ? 1 : 0;
return new_node; // this is a leaf node
}
for (int i=0;i<Nv;i++) {
if (pp->information_bit_pattern[i+first_leaf_index]>0) all_frozen_below=0;
}
if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp);
else {
#ifdef DEBUG_NEW_IMPL
printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right");
#endif
new_node->leaf=1;
new_node->all_frozen=1;
}
if (all_frozen_below==0) new_node->right=add_nodes(level-1,first_leaf_index+(Nv/2),pp);
return(new_node);
}
void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
void build_decoder_tree(t_nrPolar_params *pp) {
pp->tree.num_nodes=0;
pp->tree.root = add_nodes(pp->n,0,pp);
}
void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) {
int16_t *alpha_v=node->alpha;
int16_t *alpha_l=node->left->alpha;
int16_t *betal = node->left->beta;
int16_t a,b,absa,absb,maska,maskb,minabs;
#ifdef DEBUG_NEW_IMPL
printf("applyFtoleft %d, Nv %d (level %d,node->left (leaf %d, AF %d))\n",node->first_leaf_index,node->Nv,node->level,node->left->leaf,node->left->all_frozen);
for (int i=0;i<node->Nv;i++) printf("i%d (frozen %d): alpha_v[i] = %d\n",i,1-pp->information_bit_pattern[node->first_leaf_index+i],alpha_v[i]);
#endif
if (node->left->all_frozen == 0) {
#if defined(__AVX2__)
int avx2mod = (node->Nv/2)&15;
if (avx2mod == 0) {
__m256i a256,b256,absa256,absb256,minabs256;
int avx2len = node->Nv/2/16;
for (int i=0;i<avx2len;i++) {
a256 =((__m256i*)alpha_v)[i];
b256 =((__m256i*)alpha_v)[i+avx2len];
absa256 =_mm256_abs_epi16(a256);
absb256 =_mm256_abs_epi16(b256);
minabs256 =_mm256_min_epi16(absa256,absb256);
((__m256i*)alpha_l)[i] =_mm256_sign_epi16(minabs256,_mm256_xor_si256(a256,b256));
}
}
else if (avx2mod == 8) {
__m128i a128,b128,absa128,absb128,minabs128;
a128 =*((__m128i*)alpha_v);
b128 =((__m128i*)alpha_v)[1];
absa128 =_mm_abs_epi16(a128);
absb128 =_mm_abs_epi16(b128);
minabs128 =_mm_min_epi16(absa128,absb128);
*((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_xor_si128(a128,b128));
}
else if (avx2mod == 4) {
__m64 a64,b64,absa64,absb64,minabs64;
a64 =*((__m64*)alpha_v);
b64 =((__m64*)alpha_v)[1];
absa64 =_mm_abs_pi16(a64);
absb64 =_mm_abs_pi16(b64);
minabs64 =_mm_min_pi16(absa64,absb64);
*((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_xor_si64(a64,b64));
}
else
#endif
{
for (int i=0;i<node->Nv/2;i++) {
a=alpha_v[i];
b=alpha_v[i+(node->Nv/2)];
maska=a>>15;
maskb=b>>15;
absa=(a+maska)^maska;
absb=(b+maskb)^maskb;
minabs = absa<absb ? absa : absb;
alpha_l[i] = (maska^maskb)==0 ? minabs : -minabs;
}
}
if (node->Nv == 2) { // apply hard decision on left node
betal[0] = (alpha_l[0]>0) ? -1 : 1;
#ifdef DEBUG_NEW_IMPL
printf("betal[0] %d (%p)\n",betal[0],&betal[0]);
#endif
pp->nr_polar_u[node->first_leaf_index] = (1+betal[0])>>1;
#ifdef DEBUG_NEW_IMPL
printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]);
#endif
}
}
}
void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) {
int16_t *alpha_v=node->alpha;
int16_t *alpha_r=node->right->alpha;
int16_t *betal = node->left->beta;
int16_t *betar = node->right->beta;
#ifdef DEBUG_NEW_IMPL
printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",node->first_leaf_index,node->Nv,node->level,node->right->leaf,node->right->all_frozen);
#endif
if (node->right->all_frozen == 0) {
#if defined(__AVX2__)
int avx2mod = (node->Nv/2)&15;
if (avx2mod == 0) {
int avx2len = node->Nv/2/16;
for (int i=0;i<avx2len;i++) {
((__m256i *)alpha_r)[i] =
_mm256_subs_epi16(((__m256i *)alpha_v)[i+avx2len],
_mm256_sign_epi16(((__m256i *)alpha_v)[i],
((__m256i *)betal)[i]));
}
}
else if (avx2mod == 8) {
((__m128i *)alpha_r)[0] = _mm_subs_epi16(((__m128i *)alpha_v)[1],_mm_sign_epi16(((__m128i *)alpha_v)[0],((__m128i *)betal)[0]));
}
else
#endif
{
for (int i=0;i<node->Nv/2;i++) {
alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]);
}
}
if (node->Nv == 2) { // apply hard decision on right node
betar[0] = (alpha_r[0]>0) ? -1 : 1;
pp->nr_polar_u[node->first_leaf_index+1] = (1+betar[0])>>1;
#ifdef DEBUG_NEW_IMPL
printf("Setting bit %d to %d (LLR %d frozen_mask %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0],frozen_mask);
#endif
}
}
}
void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len) {
for (uint8_t i = 0; i < listSize; i++) {
for (uint8_t j = 0; j < len; j++) {
crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 );
}
int16_t minus1[16] = {-1,-1,-1,-1,
-1,-1,-1,-1,
-1,-1,-1,-1,
-1,-1,-1,-1};
void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) {
int16_t *betav = node->beta;
int16_t *betal = node->left->beta;
int16_t *betar = node->right->beta;
#ifdef DEBUG_NEW_IMPL
printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen);
#endif
if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits
#if defined(__AVX2__)
int avx2mod = (node->Nv/2)&15;
if (avx2mod == 0) {
int avx2len = node->Nv/2/16;
for (int i=0;i<avx2len;i++) {
((__m256i*)betav)[i] = _mm256_sign_epi16(((__m256i*)betar)[i],
((__m256i*)betal)[i]);
((__m256i*)betav)[i] = _mm256_sign_epi16(((__m256i*)betav)[i],
((__m256i*)minus1)[0]);
}
}
else if (avx2mod == 8) {
((__m128i*)betav)[0] = _mm_sign_epi16(((__m128i*)betar)[0],
((__m128i*)betal)[0]);
((__m128i*)betav)[0] = _mm_sign_epi16(((__m128i*)betav)[0],
((__m128i*)minus1)[0]);
}
else if (avx2mod == 4) {
((__m64*)betav)[0] = _mm_sign_pi16(((__m64*)betar)[0],
((__m64*)betal)[0]);
((__m64*)betav)[0] = _mm_sign_pi16(((__m64*)betav)[0],
((__m64*)minus1)[0]);
}
else
#endif
{
for (int i=0;i<node->Nv/2;i++) {
betav[i] = (betal[i] != betar[i]) ? 1 : -1;
}
}
}
else memcpy((void*)&betav[0],betar,(node->Nv/2)*sizeof(int16_t));
memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t));
}
void generic_polar_decoder(t_nrPolar_params *pp,decoder_node_t *node) {
// Apply F to left
applyFtoleft(pp,node);
// if left is not a leaf recurse down to the left
if (node->left->leaf==0) generic_polar_decoder(pp,node->left);
applyGtoright(pp,node);
if (node->right->leaf==0) generic_polar_decoder(pp,node->right);
computeBeta(pp,node);
}
......@@ -30,52 +30,144 @@
#include <stdlib.h>
#include <string.h>
#include "PHY/TOOLS/time_meas.h"
static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 };
#define Nmax 1024
#define nmax 10
typedef struct decoder_list_s {
uint8_t bit[1+nmax][Nmax];
double llr[1+nmax][Nmax];
uint8_t crcChecksum[24];
double pathMetric;
} decoder_list_t;
typedef struct decoder_list_int8_s {
uint8_t bit[1+nmax][Nmax] __attribute__((aligned(32)));
int16_t llr[1+nmax][Nmax]__attribute__((aligned(32)));
uint8_t crcChecksum[24];
int32_t pathMetric;
} decoder_list_int8_t;
typedef struct decoder_node_t_s {
struct decoder_node_t_s *left;
struct decoder_node_t_s *right;
int level;
int leaf;
int Nv;
int first_leaf_index;
int all_frozen;
int16_t *alpha;
int16_t *beta;
} decoder_node_t;
typedef struct decoder_tree_t_s {
decoder_node_t *root;
int num_nodes;
} decoder_tree_t;
struct nrPolar_params {
uint8_t n_max;
uint8_t i_il;
uint8_t i_seg;
uint8_t n_pc;
uint8_t n_pc_wm;
uint8_t i_bil;
uint16_t payloadBits;
uint16_t encoderLength;
uint8_t crcParityBits;
uint8_t crcCorrectionBits;
uint16_t K;
uint16_t N;
uint8_t n;
uint16_t *interleaving_pattern;
uint16_t *rate_matching_pattern;
const uint16_t *Q_0_Nminus1;
int16_t *Q_I_N;
int16_t *Q_F_N;
int16_t *Q_PC_N;
uint8_t *information_bit_pattern;
uint16_t *channel_interleaver_pattern;
uint32_t crc_polynomial;
uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N;
uint32_t* crc256Table;
//polar_encoder vectors:
uint8_t *nr_polar_crc;
uint8_t *nr_polar_b;
uint8_t *nr_polar_cPrime;
uint8_t *nr_polar_u;
uint8_t *nr_polar_d;
uint8_t n_max;
uint8_t i_il;
uint8_t i_seg;
uint8_t n_pc;
uint8_t n_pc_wm;
uint8_t i_bil;
uint16_t payloadBits;
uint16_t encoderLength;
uint8_t crcParityBits;
uint8_t crcCorrectionBits;
uint16_t K;
uint16_t N;
uint8_t n;
uint16_t *interleaving_pattern;
uint16_t *rate_matching_pattern;
const uint16_t *Q_0_Nminus1;
int16_t *Q_I_N;
int16_t *Q_F_N;
int16_t *Q_PC_N;
uint8_t *information_bit_pattern;
uint16_t *channel_interleaver_pattern;
uint32_t crc_polynomial;
uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N;
uint32_t* crc256Table;
uint8_t **extended_crc_generator_matrix;
//polar_encoder vectors:
uint8_t *nr_polar_crc;
uint8_t *nr_polar_b;
uint8_t *nr_polar_cPrime;
uint8_t *nr_polar_u;
uint8_t *nr_polar_d;
void (*decoder_kernel)(struct nrPolar_params *,decoder_list_int8_t **);
decoder_tree_t tree;
} __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params;
void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParams);
void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N);
void generic_polar_decoder(t_nrPolar_params *,decoder_node_t *);
int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams,
uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr);
uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR);
int8_t polar_decoder_int8(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR,
int generate_optim_code);
int8_t polar_decoder_int8_new(int16_t *input,
uint8_t *output,
t_nrPolar_params *polarParams,
uint8_t listSize,
time_stats_t *init,
time_stats_t *polar_rate_matching,
time_stats_t *decoding,
time_stats_t *bit_extraction,
time_stats_t *deinterleaving,
time_stats_t *sorting,
time_stats_t *path_metric,
time_stats_t *update_LLR,
int generate_optim_code);
void nr_polar_llrtableinit(void);
void nr_polar_init(t_nrPolar_params* polarParams, int messageType);
......@@ -94,6 +186,9 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P
void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp,
uint16_t K, uint16_t N, uint16_t E);
void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp,
uint16_t K, uint16_t N, uint16_t E);
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_);
void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N,
......@@ -114,28 +209,49 @@ void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t **
uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen,
uint16_t zlen);
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen);
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen);
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen);
void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen);
void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen);
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen);
void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen,
uint8_t ylen, uint8_t approximation);
void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize,
uint8_t bitValue, uint16_t row, uint8_t approximation);
void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize,
uint16_t row, uint8_t approximation);
void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i,
uint16_t offset, uint8_t approximation);
void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len);
void nr_free_double_2D_array(double **input, uint16_t xlen);
void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation);
void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU,
uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd);
void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen);
void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row,
uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd);
void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue,
uint16_t row, uint8_t approximation);
void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd);
void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr);
void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd);
void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd);
void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len);
void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen,
uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd);
void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len);
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len);
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits);
uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits);
......@@ -158,4 +274,144 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1
for (int i=0; i<size; i++) output[pattern[i]]=input[i];
}
void polar_decoder_K56_N512_E864(t_nrPolar_params *polarParams,decoder_list_int8_t **sorted_list);
void build_decoder_tree(t_nrPolar_params *pp);
#define updateLLR_int8_A(dlist,listSize,col,row,offset) {for (int i=0;i<listSize;i++) {if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)];if(dlist[(i)]->llr[col][row]>127 || dlist[i]->llr[col][row]<-128) printf("dlist[%d]->llr[%d][%d] = %d> 8bit\n",i,col,row,dlist[i]->llr[col][row]);}}
#define updateBit_int8_A(dlist,listSize,col,row) {for (int i=0;i<listSize;i++) {dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)];}}
#define updateBit_int8_B(dlist,listSize,col,row,offset) {for (int i=0;i<listSize;i++) {dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)];}}
#define updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr) {for (int i=0;i<listSize;i++) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}}
#define updatePathMetric2_int8_A(dlist,listSize,row) {for (int i=0;i<listSize;i++) {{dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}}}
#define updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;i<listSize;i++){for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}}
#define updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;i<listSize;i++){for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}}
extern int16_t llrtab[256][256];
inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col,
uint16_t offset) __attribute__((always_inline));
inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col,
uint16_t offset) {
int16_t a;
int16_t b;
int16_t absA,absB;
int16_t maska,maskb;
int16_t minabs;
// int16_t **llr=dlist[i]->llr;
for (int i=0;i<listSize;i++) {
a = dlist[i]->llr[col + 1][row];
b = dlist[i]->llr[col+1][row + offset];
// printf("LLR: a %d, b %d\n",a,b);
maska = a>>15;
maskb = b>>15;
absA = (a+maska)^maska;
absB = (b+maskb)^maskb;
// printf("LLR: absA %d, absB %d\n",absA,absB);
minabs = absA<absB ? absA : absB;
if ((maska^maskb) == 0)
dlist[i]->llr[col][row] = minabs;
else
dlist[i]->llr[col][row] = -minabs;
// printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]);
//dlist[i]->llr[col][row] = llrtab[a+128][b+128];
// printf("newLLR [%d,%d]: %d\n",col,row,dlist[i]->llr[col][row]);
}
}
#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \
for (int k = 0; k < (polarParams->n+1); k++) { \
memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\
(void*)&sorted_dlist[i]->bit[k][0],\
sizeof(uint8_t)*polarParams->N);\
memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\
(void*)&sorted_dlist[i]->llr[k][0],\
sizeof(int16_t)*polarParams->N);}}}
#define decoder_int8_B(sorted_dlist,currentBit,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}}
void inline decoder_int8_C(decoder_list_int8_t *sorted_dlist[],
t_nrPolar_params *polarParams,
int currentBit,
int currentListSize,
int listSize) {
int32_t pathMetric[2*listSize];
decoder_list_int8_t *temp_dlist[2*listSize];
int listIndex[2*listSize];
int listIndex2[2*listSize];
for (int i = 0; i < currentListSize; i++) {
listIndex[i]=i;
pathMetric[i] = sorted_dlist[i]->pathMetric;
}
nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize);
for (int i=0;i<currentListSize;i++) {
listIndex2[listIndex[i]] = i;
}
// copy the llr/bit arrays that are needed
for (int i = 0; i < listSize; i++) {
// printf("listIndex[%d] %d\n",i,listIndex[i]);
if ((listIndex2[i+listSize]<listSize) && (listIndex2[i]<listSize)) { // both '0' and '1' path metrics are to be kept
// do memcpy of LLR and Bit arrays
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
sorted_dlist[i]->bit[0][currentBit]=0;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
}
else if (listIndex2[i+listSize]<listSize) { // only '1' path metric is to be kept
// just change the current bit from '0' to '1'
for (int k = 0; k < (polarParams->n+1); k++) {
memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0],
(void*)&sorted_dlist[i]->bit[k][0],
sizeof(uint8_t)*polarParams->N);
memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0],
(void*)&sorted_dlist[i]->llr[k][0],
sizeof(int16_t)*polarParams->N);
}
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
/*
decoder_list_t *tmp = sorted_dlist[i+listSize];
sorted_dlist[i+listSize] = sorted_dlist[i];
sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric;
sorted_dlist[i+listSize]->bit[0][currentBit]=1;
memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0],
(void*)&tmp->crcChecksum[0],
24*sizeof(uint8_t));*/
}
}
for (int i = 0; i < 2*listSize; i++) {
temp_dlist[i] = sorted_dlist[i];
}
for (int i = 0; i < 2*listSize; i++) {
// printf("i %d => %d\n",i,listIndex[i]);
sorted_dlist[i] = temp_dlist[listIndex[i]];
}
}
#endif
......@@ -66,38 +66,30 @@ uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen
return output;
}
double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) {
double ***output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 2D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = NULL;
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 3D allocation");
nr_free_double_3D_array(output, xlen, ylen);
return NULL;
}
return output;
double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen) {
double **output;
int i, j;
if ((output = malloc(xlen * sizeof(*output))) == NULL) {
perror("[nr_alloc_double_3D_array] Problem at 1D allocation");
return NULL;
}
for (i = 0; i < xlen; i++)
output[i] = NULL;
for (i = 0; i < xlen; i++)
if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) {
perror("[nr_alloc_double_2D_array] Problem at 2D allocation");
nr_free_double_2D_array(output, xlen);
return NULL;
}
for (i = 0; i < xlen; i++)
for (j = 0; j < ylen; j++)
output[i][j] = 0;
return output;
}
uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
......@@ -138,31 +130,28 @@ void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) {
}
void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) {
for (int i = 0; i < xlen; i++) free(input[i]);
free(input);
for (int i = 0; i < xlen; i++) free(input[i]);
free(input);
}
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]);
}
free(input);
void nr_free_double_2D_array(double **input, uint16_t xlen) {
int i;
for (i = 0; i < xlen; i++) {
free(input[i]);
}
free(input);
}
// Modified Bubble Sort.
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) {
uint8_t swaps;
void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) {
int swaps;
double temp;
uint8_t tempInd;
int tempInd;
for (uint8_t i = 0; i < len; i++) {
for (int i = 0; i < len; i++) {
swaps = 0;
for (uint8_t j = 0; j < (len - i) - 1; j++) {
for (int j = 0; j < (len - i) - 1; j++) {
if (matrix[j] > matrix[j + 1]) {
temp = matrix[j];
matrix[j] = matrix[j + 1];
......@@ -179,3 +168,28 @@ void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len)
break;
}
}
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len) {
int swaps;
int16_t temp;
int tempInd;
for (int i = 0; i < len; i++) {
swaps = 0;
for (int j = 0; j < (len - i) - 1; j++) {
if (matrix[j] > matrix[j + 1]) {
temp = matrix[j];
matrix[j] = matrix[j + 1];
matrix[j + 1] = temp;
tempInd = ind[j];
ind[j] = ind[j + 1];
ind[j + 1] = tempInd;
swaps++;
}
}
if (swaps == 0)
break;
}
}
......@@ -79,3 +79,24 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16
}
}
void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){
if (E>=N) { //repetition
for (int i=0; i<=N-1; i++) output[i]=0;
for (int i=0; i<=E-1; i++){
output[rmp[i]]+=input[i];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int i=0; i<=N-1; i++) output[i]=0;
} else { //shortening
for (int i=0; i<=N-1; i++) output[i]=INFINITY;
}
for (int i=0; i<=E-1; i++){
output[rmp[i]]=input[i];
}
}
}
......@@ -220,7 +220,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t nushift;
uint8_t *xbyte = pbch->pbch_a;
memset((void*) xbyte, 0, 1);
uint8_t pbch_a_b[32];
//uint8_t pbch_a_b[32];
LOG_I(PHY, "PBCH generation started\n");
......@@ -283,10 +283,10 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
printf("pbch_a_prime[%d]: 0x%02x\n", i, pbch->pbch_a_prime[i]);
#endif
for (int m=0;m<32;m++){
pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01);
//for (int m=0;m<32;m++){
//pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01);
//printf("pbch_a_b[%d] %d\n", m, pbch_a_b[m] );
}
//}
/// CRC, coding and rate matching
polar_encoder (pbch->pbch_a_prime, pbch->pbch_e, &frame_parms->pbch_polar_params);
......
......@@ -35,6 +35,7 @@
#include "PHY/defs_nr_UE.h"
//#include "PHY/extern.h"
//#include "LAYER2/MAC/extern.h"
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
......@@ -44,269 +45,8 @@
#define DEBUG_PUCCH_TX
#define DEBUG_NR_PUCCH_TX
#endif
#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
/*
* The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1)
* Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24}
* For M_ZC=30, base sequence r_u_v(n)=exp[-j((pi*[u+1]*[n+1]*[n+2])/31)]
*/
int16_t table_5_2_2_2_1_Re[30][6]={ // Table 5.2.2.2-1 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6)
{-23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{ 23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170},
{-23170,-23170, 23170, 23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170, 23170, 23170,-23170, 23170},
{ 23170, 23170, 23170,-23170, 23170, 23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{ 23170, 23170,-23170, 23170, 23170, 23170}
};
int16_t table_5_2_2_2_1_Im[30][6]={ // Table 5.2.2.2-1 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6)
{-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170, 23170,-23170},
{ 23170, 23170, 23170, 23170,-23170,-23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170, 23170,-23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{ 23170, 23170, 23170, 23170,-23170, 23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170, 23170},
{ 23170, 23170,-23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170}
};
int16_t table_5_2_2_2_2_Re[30][12]={ // Table 5.2.2.2-2 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12)
{-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{ 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170},
{ 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170},
{-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170},
{-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}
};
int16_t table_5_2_2_2_2_Im[30][12]={ // Table 5.2.2.2-2 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12)
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170},
{-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170},
{ 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170},
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170},
{-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170},
{-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{ 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170},
{-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170}
};
int16_t table_5_2_2_2_3_Re[30][18]={ // Table 5.2.2.2-3 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18)
{ 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170},
{-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170},
{-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170},
{ 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170},
{-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170},
{ 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170},
{-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170},
{ 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170},
{-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170},
{-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{ 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170},
{-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{ 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170}
};
int16_t table_5_2_2_2_3_Im[30][18]={ // Table 5.2.2.2-3 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18)
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{ 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170},
{ 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170},
{ 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170},
{-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170},
{ 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170},
{-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170},
{ 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170},
{-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{ 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170},
{-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170},
{-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}
};
int16_t table_5_2_2_2_4_Re[30][24]={ // Table 5.2.2.2-4 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24)
{ 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170},
{ 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{ 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170},
{ 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}
};
int16_t table_5_2_2_2_4_Im[30][24]={ // Table 5.2.2.2-4 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24)
{-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170},
{ 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{ 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170}
};
void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_nr.puch_GroupHopping,
//uint8_t PUCCH_GroupHopping,
PHY_VARS_NR_UE *ue,
......@@ -336,13 +76,12 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n
uint16_t n_id = ue->pucch_config_common_nr->hoppingId; // from higher layers FIXME!!!
//////////////////////////////////////initialization to be removed///////////////////////////////////////////////////////////
PUCCH_GroupHopping=neither;
n_id=10;
#ifdef DEBUG_NR_PUCCH_TX
// initialization to be removed
PUCCH_GroupHopping=neither;
n_id=10;
printf("\t\t [nr_group_sequence_hopping] initialization PUCCH_GroupHopping=%d, n_id=%d -> variable initializations TO BE REMOVED\n",PUCCH_GroupHopping,n_id);
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t f_ss=0,f_gh=0;
......@@ -373,6 +112,7 @@ void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_n
printf("%d,%d\n",*u,*v);
#endif
}
double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue,
uint8_t m0,
uint8_t mcs,
......@@ -391,14 +131,11 @@ double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue,
double alpha = 0.5235987756;
uint16_t c_init = ue->pucch_config_common_nr->hoppingId; // we initialize c_init again to calculate n_cs
//////////////////////////////////////initialization to be removed///////////////////////////////////////////////////////////
#ifdef DEBUG_NR_PUCCH_TX
// initialization to be removed
c_init=10;
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init);
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
printf("\t\t [nr_cyclic_shift_hopping] initialization c_init=%d -> variable initialization TO BE REMOVED\n",c_init);
#endif
uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1
uint8_t n_cs=0;
......@@ -438,11 +175,6 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
printf("\t [nr_generate_pucch0] sequence generation\n");
#endif
// number of symbols defined in the PUCCH-Config from higher layers: format 0 {1-2} FIXME!
//uint8_t nrofSymbols;
//uint8_t startingSymbolIndex;
//uint8_t startingPRB;
/*
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/
......@@ -542,6 +274,7 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
}
}
}
void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
......@@ -557,69 +290,300 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
uint8_t timeDomainOCC,
uint8_t nr_bit) {
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d\n",nr_tti_tx);
printf("\t [nr_generate_pucch1] startingPRB=%d startingPRB_intraSlotHopping=%d\n",startingPRB,startingPRB_intraSlotHopping);
printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
#endif
/*
* The following tables implement TS 38.211 table 6.3.2.4.1-1: Number of PUCCH symbols and the corresponding N_SF_mprime_PUCCH_1
* One table for no intra-slot hopping
* Two tables for intra-slot hopping (mprime=0 and mprime=1)
*/
uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,2,3,3,4,4,5,5,6,6,7}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping
uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,1,1,2,2,2,2,3,3,3}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0
uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1
* Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
*
*/
// complex-valued symbol d_re, d_im containing complex-valued symbol d(0):
int16_t d_re, d_im;
if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
}
if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
if (((payload&1)==0) && (((payload>>1)&1)==0)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
}
if (((payload&1)==0) && (((payload>>1)&1)==1)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
}
if (((payload&1)==1) && (((payload>>1)&1)==0)) {
d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
}
if (((payload&1)==1) && (((payload>>1)&1)==1)) {
d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
}
}
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence modulation: payload=%x \tde_re=%d \tde_im=%d\n",payload,d_re,d_im);
#endif
/*
* Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
*/
// alpha is cyclic shift
double alpha;
// lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission
uint8_t lnormal = 0 ;
// lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213]
uint8_t lprime = startingSymbolIndex;
// mcs = 0 except for PUCCH format 0
uint8_t mcs=0;
// r_u_v_alpha_delta_re and r_u_v_alpha_delta_im tables containing the sequence y(n) for the PUCCH, when they are multiplied by d(0)
// r_u_v_alpha_delta_dmrs_re and r_u_v_alpha_delta_dmrs_im tables containing the sequence for the DM-RS.
int16_t r_u_v_alpha_delta_re[12],r_u_v_alpha_delta_im[12],r_u_v_alpha_delta_dmrs_re[12],r_u_v_alpha_delta_dmrs_im[12];
/*
* The following tables implement TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_SF_mprime_PUCCH_1
* One table for no intra-slot hopping
* Two tables for intra-slot hopping (mprime=0 and mprime=1)
* in TS 38.213 Subclause 9.2.1 it is said that:
* for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift
* is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift
*/
/*
* the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n)
*/
// the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
uint8_t u=0,v=0,delta=0;
// if frequency hopping is disabled, intraSlotFrequencyHopping is not provided
// n_hop = 0
// if frequency hopping is enabled, intraSlotFrequencyHopping is provided
// n_hop = 0 for first hop
// n_hop = 1 for second hop
uint8_t n_hop = 0;
// Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided,
// regardless of whether the frequency-hop distance is zero or not,
// otherwise no intra-slot frequency hopping shall be assumed
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
uint8_t intraSlotFrequencyHopping = 0;
if (startingPRB != startingPRB_intraSlotHopping){
intraSlotFrequencyHopping=1;
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping);
#endif
}
/*
* Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources
*/
uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,3,3,4,4,5,5,6,6,7,7}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping
uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0
uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,2,1,2,2,3,2,3,3,4,3}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1
/* The following tables implement TS 38.211 table 6.3.2.4.1-2: Orthogonal sequences wi(m)=exp(j*2*pi*phi(m)/N_SF) for PUCCH format 1
uint16_t table_6_3_2_4_1_2_W2[2][2] = {{0,0}, {0,1}};
uint16_t table_6_3_2_4_1_2_W3[3][3] = {{0,0,0}, {0,1,2}, {0,2,1}};
uint16_t table_6_3_2_4_1_2_W4[4][4] = {{0,0,0,0}, {0,2,0,2}, {0,0,2,2} , {0,2,2,0}};
uint16_t table_6_3_2_4_1_2_W5[2][2] = {{0,0,0,0,0}, {0,1,2,3,4}, {0,2,4,1,3}, {0,3,1,4,2}, {0,4,3,2,1}};
uint16_t table_6_3_2_4_1_2_W6[2][2] = {{0,0,0,0,0,0}, {0,1,2,3,4,5}, {0,2,4,0,2,4}, {0,3,0,3,0,3}, {0,4,2,0,4,2}, {0,5,4,3,2,1}};
uint16_t table_6_3_2_4_1_2_W7[2][2] = {{0,0,0,0,0,0,0},{0,1,2,3,4,5,6},{0,2,4,6,1,3,5},{0,3,6,2,5,1,4},{0,4,1,5,2,6,3},{0,5,3,1,6,4,2},{0,6,5,4,3,2,1}};
*/
int16_t table_6_3_2_4_1_2_Wi_Re[8][7][7] = {
{{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,0,0,0,0,0}, {32767,-32767,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,0,0,0}, {32767,-32767,32767,-32767,0,0,0}, {32767,32767,-32767,-32767,0,0,0}, {32767,-32767,-32767,32767,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,32767,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,32767,32767,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,-32767,32767,-32767,32767,-32767,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,32767,32767,32767},{32767,20430,-7291,-29522,-29522,-7291,20430},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,20430,-7291,-29522,-29522,-7291,20430}}
};
int16_t table_6_3_2_4_1_2_Wi_Im[8][7][7] = {
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,28377,-28377,0,0,0,0}, {0,-28377,28377,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,31163,19260,-19260,-31163,0,0}, {0,19260,-31163,31163,-19260,0,0}, {0,-19260,31163,-31163,19260,0,0}, {0,-31163,-19260,19260,31163,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,28377,28377,0,-28377,-28377,0}, {0,28377,-28377,0,28377,-28377,0}, {0,0,0,0,0,0,0}, {0,-28377,28377,0,-28377,28377,0}, {0,-28377,-28377,0,28377,28377,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,25618,31945,14217,-14217,-31945,-25618},{0,31945,-14217,-25618,25618,14217,-31945},{0,14217,-25618,31945,-31945,25618,-14217},{0,-14217,25618,-31945,31945,-25618,14217},{0,-31945,14217,25618,-25618,-14217,31945},{0,-25618,-31945,-14217,14217,31945,25618}}
};
int32_t *txptr;
uint32_t re_offset;
int i=0;
#define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n
int16_t z_re[MAX_SIZE_Z],z_im[MAX_SIZE_Z];
int16_t z_dmrs_re[MAX_SIZE_Z],z_dmrs_im[MAX_SIZE_Z];
for (int l=0; l<nrofSymbols; l++) {
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n",
l,lprime);
#endif
// y_n contains the complex value d multiplied by the sequence r_u_v
int16_t y_n_re[12],y_n_im[12];
if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n",
n_hop,nr_tti_tx);
#endif
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,lprime,nr_tti_tx);
for (int n=0; n<12; n++){
r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha
r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
+ (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha
r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15)
- (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha
r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15)
+ (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha
// PUCCH sequence = DM-RS sequence multiplied by d(0)
y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15)
- (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n)
y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15)
+ (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n)
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n",
u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]);
#endif
}
/*
* The block of complex-valued symbols y(n) shall be block-wise spread with the orthogonal sequence wi(m)
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
* z(mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n)
*
* The block of complex-valued symbols r_u_v_alpha_dmrs_delta(n) for DM-RS shall be block-wise spread with the orthogonal sequence wi(m)
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
* z(mprime*12*table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n)
*
*/
// the orthogonal sequence index for wi(m) defined in TS 38.213 Subclause 9.2.1
// the index of the orthogonal cover code is from a set determined as described in [4, TS 38.211]
// and is indicated by higher layer parameter PUCCH-F1-time-domain-OCC
// In the PUCCH_Config IE, the PUCCH-format1, timeDomainOCC field
uint8_t w_index = timeDomainOCC;
// N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled)
uint8_t N_SF_mprime_PUCCH_1;
// N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled)
uint8_t N_SF_mprime_PUCCH_DMRS_1;
// N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled)
uint8_t N_SF_mprime0_PUCCH_1;
// N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled)
uint8_t N_SF_mprime0_PUCCH_DMRS_1;
// mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping
uint8_t mprime = 0;
if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n",
intraSlotFrequencyHopping);
#endif
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS)
N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH)
N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS)
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){
for (int n=0; n<12 ; n++){
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15));
z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15));
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t z_pucch[%d] \t= ((%d \t* %d \t-%d \t* %d), (%d \t* %d \t+%d \t*%d)) = (%d,%d)\n",
(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n,
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],
table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif
}
}
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){
for (int n=0; n<12 ; n++){
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15));
z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15));
#ifdef DEBUG_NR_PUCCH_TX
printf("\t\t z_dm-rs[%d] = ((),()) =(%d,%d)\n",
(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]);
#endif
}
}
}
if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d\n",
intraSlotFrequencyHopping);
#endif
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS)
N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH)
N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS)
for (mprime = 0; mprime<2; mprime++){ // mprime can get values {0,1}
for (int m=0; m < N_SF_mprime_PUCCH_1; m++){
for (int n=0; n<12 ; n++){
z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15));
z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15));
}
}
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++){
for (int n=0; n<12 ; n++){
z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15)
- (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15));
z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_im[n])>>15)
+ (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*r_u_v_alpha_delta_re[n])>>15));
}
}
N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH)
N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS)
}
}
if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
startingPRB = startingPRB + startingPRB_intraSlotHopping;
}
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
}
if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1)));
}
if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
}
if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6;
}
if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset;
}
txptr = &txdataF[0][re_offset];
for (int n=0; n<12; n++){
if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) {
// if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB)
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size);
}
if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1
((int16_t *)&txdataF[0][re_offset])[0] = z_re[i+n];
((int16_t *)&txdataF[0][re_offset])[1] = z_im[i+n];
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif
}
if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1
((int16_t *)&txdataF[0][re_offset])[0] = z_dmrs_re[i+n];
((int16_t *)&txdataF[0][re_offset])[1] = z_dmrs_im[i+n];
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%d)=(x_n(l=%d,n=%d)=(%d,%d))\n",
amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset,
l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]);
#endif
}
re_offset++;
}
if (l%2 == 1) i+=12;
}
}
#if 0
void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_tti_tx,
uint8_t m0,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t timeDomainOCC,
uint8_t nr_bit) {
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n",
nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit);
#endif
/*
* Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation
*
*/
// nr_bit = {1,2}, to be provided in function call. FIXME!
//uint8_t M_bit=1;
//#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
// complex-valued symbol d_re, d_im containing complex-valued symbol d(0):
int16_t d_re, d_im;
if (nr_bit == 1){ // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
if (nr_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2
d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
}
else { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
if (nr_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2
if (((payload&1)==0) && (((payload>>1)&1)==0)) {
d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15);
......@@ -863,6 +827,7 @@ void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
if (l%2 == 1) i+=12;
}
}
#endif //0
inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) __attribute__((always_inline));
inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint32_t B,uint8_t *btilde) {
......@@ -1153,8 +1118,14 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
// Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided,
// regardless of whether the frequency-hop distance is zero or not,
// otherwise no intra-slot frequency hopping shall be assumed
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers. Let's suppose we do not support intra-slot hopping FIXME!!
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
uint8_t intraSlotFrequencyHopping = 0;
if (startingPRB != startingPRB_intraSlotHopping){
intraSlotFrequencyHopping=1;
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping);
#endif
}
// add_dmrs indicates if we are using or not Additional DM-RS for formats 3 and 4. From higher layers. FIXME!!!
uint8_t add_dmrs = 0;
nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b,&M_bit);
......@@ -1349,7 +1320,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
}
/*
* Implementing TS 38.211 Subclauses 6.3.2.5.3 and 6.3.2.6.5 Mapping to physical resources FIXME!
* Implementing TS 38.211 Subclauses 6.3.2.5.3 and 6.3.2.6.5 Mapping to physical resources
*/
// the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
uint8_t u=0,v=0,delta=0;
......@@ -1381,49 +1352,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
int16_t *r_u_v_base_im = malloc(sizeof(int16_t)*12*nrofPRB);
int16_t *r_u_v_alpha_delta_re = malloc(sizeof(int16_t)*12*nrofPRB);
int16_t *r_u_v_alpha_delta_im = malloc(sizeof(int16_t)*12*nrofPRB);
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
// Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33
if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies
uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101,103,107,109,113,
127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199};
int i = 4;
while (list_of_prime_numbers[i] < (12*nrofPRB)) i++;
N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB)
double q_base = (N_ZC*(u+1))/31;
int8_t q = (uint8_t)floor(q_base + (1/2));
q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v);
for (int n=0; n<(12*nrofPRB); n++){
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15);
r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif
}
}
if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies
for (int n=0; n<(12*nrofPRB); n++){
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15);
r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif
}
}
if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies
for (int n=0; n<(12*nrofPRB); n++){
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15);
r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif
}
}
// Next we proceed to mapping to physical resources according to TS 38.211, subclause 6.3.2.6.5 dor PUCCH formats 3 and 4 and subclause 6.4.1.3.3.2 for DM-RS
int32_t *txptr;
uint32_t re_offset;
......@@ -1445,9 +1374,57 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
};
uint16_t k=0;
for (int l=0; l<nrofSymbols; l++) {
if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop
nr_group_sequence_hopping(ue,n_hop,nr_tti_tx,&u,&v); // calculating u and v value
// Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33
if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies
int i = 4;
while (list_of_prime_numbers[i] < (12*nrofPRB)) i++;
N_ZC = list_of_prime_numbers[i+1]; // N_ZC is given by the largest prime number such that N_ZC < (12*nrofPRB)
double q_base = (N_ZC*(u+1))/31;
int8_t q = (uint8_t)floor(q_base + (1/2));
q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v);
for (int n=0; n<(12*nrofPRB); n++){
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15);
r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif
}
}
if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies
for (int n=0; n<(12*nrofPRB); n++){
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15);
r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif
}
}
if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies
for (int n=0; n<(12*nrofPRB); n++){
r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15);
r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15);
#ifdef DEBUG_NR_PUCCH_TX
printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n",
nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]);
#endif
}
}
uint16_t j=0;
alpha = nr_cyclic_shift_hopping(ue,m0,mcs,l,startingSymbolIndex,nr_tti_tx);
for (int rb=0; rb<nrofPRB; rb++){
if ((intraSlotFrequencyHopping == 1) && (l<floor(nrofSymbols/2))) { // intra-slot hopping enabled, we need to calculate new offset PRB
startingPRB = startingPRB + startingPRB_intraSlotHopping;
}
//startingPRB = startingPRB + rb;
if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset;
......
/*
* 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
*/
/*! \file PHY/NR_UE_TRANSPORT/pucch_nr.c
* \brief Top-level routines for generating and decoding the PUCCH physical channel
* \author A. Mico Pereperez
* \date 2018
* \version 0.1
* \company Eurecom
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
#include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
//#include "PHY/extern.h"
//#include "LAYER2/MAC/extern.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "T.h"
#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2)
void nr_group_sequence_hopping (//pucch_GroupHopping_t ue->pucch_config_common_nr.puch_GroupHopping,
//uint8_t PUCCH_GroupHopping,
PHY_VARS_NR_UE *ue,
//uint32_t n_id,
uint8_t n_hop,
int nr_tti_tx,
uint8_t *u,
uint8_t *v);
double nr_cyclic_shift_hopping(PHY_VARS_NR_UE *ue,
uint8_t m0,
uint8_t mcs,
uint8_t lnormal,
uint8_t lprime,
int nr_tti_tx);
void nr_generate_pucch0(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
int16_t amp,
int nr_tti_tx,
uint8_t m0,
uint8_t mcs,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB);
void nr_generate_pucch1(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_tti_tx,
uint8_t m0,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t timeDomainOCC,
uint8_t nr_bit);
void nr_generate_pucch2(PHY_VARS_NR_UE *ue,
int32_t **txdataF,
NR_DL_FRAME_PARMS *frame_parms,
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
uint64_t payload,
int16_t amp,
int nr_tti_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint8_t nr_bit);
void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue,
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_tti_tx,
uint8_t nrofSymbols,
uint8_t startingSymbolIndex,
uint8_t nrofPRB,
uint16_t startingPRB,
uint16_t startingPRB_intraSlotHopping,
uint8_t nr_bit,
uint8_t occ_length_format4,
uint8_t occ_index_format4);
/*
* The following tables implement TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (rows->u {0,1,..,29} / columns->n {0,1,...,M_ZC-1)
* Where base sequence r_u_v(n)=exp[j*phi(n)*pi/4] 0<=n<=M_ZC-1 and M_ZC={6,12,18,24}
* For M_ZC=30, base sequence r_u_v(n)=exp[-j((pi*[u+1]*[n+1]*[n+2])/31)]
*/
int16_t table_5_2_2_2_1_Re[30][6]={ // Table 5.2.2.2-1 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6)
{-23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{ 23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170},
{-23170,-23170, 23170, 23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170, 23170, 23170,-23170, 23170},
{ 23170, 23170, 23170,-23170, 23170, 23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{ 23170, 23170,-23170, 23170, 23170, 23170}
};
int16_t table_5_2_2_2_1_Im[30][6]={ // Table 5.2.2.2-1 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=6)
{-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170, 23170,-23170},
{ 23170, 23170, 23170, 23170,-23170,-23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170, 23170,-23170},
{ 23170, 23170, 23170,-23170,-23170, 23170},
{ 23170, 23170, 23170, 23170,-23170, 23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170,-23170, 23170, 23170},
{ 23170, 23170,-23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170},
{ 23170, 23170,-23170, 23170,-23170,-23170}
};
int16_t table_5_2_2_2_2_Re[30][12]={ // Table 5.2.2.2-2 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12)
{-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{ 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170},
{ 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170},
{-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170},
{-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170}
};
int16_t table_5_2_2_2_2_Im[30][12]={ // Table 5.2.2.2-2 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=12)
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170},
{-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170},
{ 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170},
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170},
{-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170},
{ 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170},
{-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{ 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170},
{-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170}
};
int16_t table_5_2_2_2_3_Re[30][18]={ // Table 5.2.2.2-3 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18)
{ 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170},
{-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170},
{-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170},
{ 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170},
{-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170},
{ 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170},
{-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170},
{ 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170},
{-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170},
{-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{ 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170},
{-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170},
{ 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170}
};
int16_t table_5_2_2_2_3_Im[30][18]={ // Table 5.2.2.2-3 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=18)
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{ 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170},
{ 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170},
{ 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170},
{-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170},
{ 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170},
{-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170},
{ 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170},
{-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170},
{ 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170},
{-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170},
{-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{ 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170},
{-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170},
{ 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170},
{-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170},
{-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170}
};
int16_t table_5_2_2_2_4_Re[30][24]={ // Table 5.2.2.2-4 (Re part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24)
{ 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170},
{ 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{ 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170},
{ 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170}
};
int16_t table_5_2_2_2_4_Im[30][24]={ // Table 5.2.2.2-4 (Im part) TS 38.211 Subclause 5.2.2.2 Base sequences of length less than 36 (M_ZC=24)
{-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170},
{-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170},
{ 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170},
{ 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170},
{-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170},
{ 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170},
{-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170},
{-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170},
{ 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170,-23170,-23170},
{-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170,-23170,-23170},
{ 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170},
{-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170, 23170,-23170,-23170},
{-23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170, 23170,-23170, 23170, 23170,-23170,-23170,-23170},
{-23170, 23170,-23170, 23170,-23170, 23170, 23170, 23170, 23170,-23170,-23170,-23170, 23170, 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170,-23170,-23170},
{ 23170,-23170,-23170, 23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170,-23170,-23170,-23170, 23170,-23170, 23170, 23170, 23170,-23170, 23170,-23170,-23170,-23170}
};
/*
* The following tables implement TS 38.211 table 6.3.2.4.1-1: Number of PUCCH symbols and the corresponding N_SF_mprime_PUCCH_1
* One table for no intra-slot hopping
* Two tables for intra-slot hopping (mprime=0 and mprime=1)
*/
uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,2,3,3,4,4,5,5,6,6,7}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping
uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,1,1,2,2,2,2,3,3,3}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0
uint8_t table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1
/*
* The following tables implement TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_SF_mprime_PUCCH_1
* One table for no intra-slot hopping
* Two tables for intra-slot hopping (mprime=0 and mprime=1)
*/
uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[14] = {0,0,0,2,3,3,4,4,5,5,6,6,7,7}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when no intra-slot hopping
uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[14] = {0,0,0,1,1,2,2,2,2,3,3,3,3,4}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=0
uint8_t table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[14] = {0,0,0,1,2,1,2,2,3,2,3,3,4,3}; // for index PUCCH-DM-RS-length, we obtain N_SF_mprime_PUCCH_1 when intra-slot hopping and mprime=1
/* The following tables implement TS 38.211 table 6.3.2.4.1-2: Orthogonal sequences wi(m)=exp(j*2*pi*phi(m)/N_SF) for PUCCH format 1
uint16_t table_6_3_2_4_1_2_W2[2][2] = {{0,0}, {0,1}};
uint16_t table_6_3_2_4_1_2_W3[3][3] = {{0,0,0}, {0,1,2}, {0,2,1}};
uint16_t table_6_3_2_4_1_2_W4[4][4] = {{0,0,0,0}, {0,2,0,2}, {0,0,2,2} , {0,2,2,0}};
uint16_t table_6_3_2_4_1_2_W5[2][2] = {{0,0,0,0,0}, {0,1,2,3,4}, {0,2,4,1,3}, {0,3,1,4,2}, {0,4,3,2,1}};
uint16_t table_6_3_2_4_1_2_W6[2][2] = {{0,0,0,0,0,0}, {0,1,2,3,4,5}, {0,2,4,0,2,4}, {0,3,0,3,0,3}, {0,4,2,0,4,2}, {0,5,4,3,2,1}};
uint16_t table_6_3_2_4_1_2_W7[2][2] = {{0,0,0,0,0,0,0},{0,1,2,3,4,5,6},{0,2,4,6,1,3,5},{0,3,6,2,5,1,4},{0,4,1,5,2,6,3},{0,5,3,1,6,4,2},{0,6,5,4,3,2,1}};
*/
int16_t table_6_3_2_4_1_2_Wi_Re[8][7][7] = {
{{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,0,0,0,0,0}, {32767,-32767,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {32767,-16384,-16384,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,0,0,0}, {32767,-32767,32767,-32767,0,0,0}, {32767,32767,-32767,-32767,0,0,0}, {32767,-32767,-32767,32767,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,32767,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,-26509,10126,10126,-26509,0,0}, {32767,10126,-26509,-26509,10126,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,32767,32767,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,-32767,32767,-32767,32767,-32767,0}, {32767,-16384,-16384,32767,-16384,-16384,0}, {32767,16384,-16384,-32767,-16384,16384,0}, {0,0,0,0,0,0,0}},
{{32767,32767,32767,32767,32767,32767,32767},{32767,20430,-7291,-29522,-29522,-7291,20430},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-29522,20430,-7291,-7291,20430,-29522},{32767,-7291,-29522,20430,20430,-29522,-7291},{32767,20430,-7291,-29522,-29522,-7291,20430}}
};
int16_t table_6_3_2_4_1_2_Wi_Im[8][7][7] = {
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,28377,-28377,0,0,0,0}, {0,-28377,28377,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,31163,19260,-19260,-31163,0,0}, {0,19260,-31163,31163,-19260,0,0}, {0,-19260,31163,-31163,19260,0,0}, {0,-31163,-19260,19260,31163,0,0}, {0,0,0,0,0,0,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,28377,28377,0,-28377,-28377,0}, {0,28377,-28377,0,28377,-28377,0}, {0,0,0,0,0,0,0}, {0,-28377,28377,0,-28377,28377,0}, {0,-28377,-28377,0,28377,28377,0}, {0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0},{0,25618,31945,14217,-14217,-31945,-25618},{0,31945,-14217,-25618,25618,14217,-31945},{0,14217,-25618,31945,-31945,25618,-14217},{0,-14217,25618,-31945,31945,-25618,14217},{0,-31945,14217,25618,-25618,-14217,31945},{0,-25618,-31945,-14217,14217,31945,25618}}
};
uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101,103,107,109,113,
127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199};
......@@ -101,8 +101,7 @@ void nr_feptx_ofdm_2thread(RU_t *ru) {
// this copy should be done in the precoding thread (currently inactive)
for (int aa=0;aa<ru->nb_tx;aa++)
memcpy((void*)ru->common.txdataF_BF[aa],
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa][subframe*fp->samples_per_subframe_wCP],
fp->samples_per_subframe_wCP*sizeof(int32_t));
(void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_subframe_wCP*sizeof(int32_t));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
......
......@@ -170,8 +170,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
// clear the transmit data array for the current subframe
for (aa=0; aa<cfg->rf_config.tx_antenna_ports.value; aa++) {
memset(&gNB->common_vars.txdataF[aa][subframe*fp->samples_per_subframe_wCP],
0,fp->samples_per_subframe_wCP*sizeof(int32_t));
memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_subframe_wCP*sizeof(int32_t));
}
if (nfapi_mode == 0 || nfapi_mode == 1) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment