Commit 340331dc authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge remote-tracking branch 'origin/develop-nr' into nr-emulate-rf

parents 7222441f 632a588b
......@@ -315,8 +315,8 @@ elseif (${RRC_ASN1_VERSION} STREQUAL "Rel14")
make_version(RRC_VERSION 14 7 0)
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-14.7.0.asn1)
elseif (${RRC_ASN1_VERSION} STREQUAL "Rel15")
make_version(RRC_VERSION 15 2 2)
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/RRC-36331-f22.asn)
make_version(RRC_VERSION 15 3 0)
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.3.0.asn1)
endif (${RRC_ASN1_VERSION} STREQUAL "Rel8")
add_definitions(-DRRC_VERSION=${RRC_VERSION})
set (RRC_FULL_DIR ${asn1_generated_dir}/RRC_${RRC_ASN1_VERSION})
......@@ -355,8 +355,8 @@ add_custom_command (
add_list2_option(NR_RRC_ASN1_VERSION "NR_Rel15" "ASN.1 version of NR_RRC interface")
if (${NR_RRC_ASN1_VERSION} STREQUAL "NR_Rel15")
make_version(NR_RRC_VERSION 15 2 1)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-15.2.1.asn1)
make_version(NR_RRC_VERSION 15 3 0)
set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-15.3.0.asn1)
endif (${NR_RRC_ASN1_VERSION} STREQUAL "NR_Rel15")
add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION})
set (NR_RRC_FULL_DIR ${asn1_generated_dir}/${NR_RRC_ASN1_VERSION})
......@@ -394,7 +394,7 @@ add_custom_command (OUTPUT ${NR_RRC_FULL_DIR}/NR_asn_constant.h
# Same limitation as described in RRC: unknown generated file list
# so we generate it at cmake time
##############
add_list1_option(S1AP_RELEASE R14 "S1AP ASN.1 grammar version" R8 R9 R10 R14 R15)
add_list1_option(S1AP_RELEASE R15 "S1AP ASN.1 grammar version" R8 R9 R10 R14 R15)
set(S1AP_DIR ${OPENAIR3_DIR}/S1AP)
if (${S1AP_RELEASE} STREQUAL "R8")
......@@ -416,11 +416,11 @@ elseif (${S1AP_RELEASE} STREQUAL "R13")
make_version(S1AP_VERSION 13 6 0)
set(S1AP_ASN_FILES "s1ap-13.6.0.asn1")
elseif (${S1AP_RELEASE} STREQUAL "R14")
make_version(S1AP_VERSION 14 5 0)
set(S1AP_ASN_FILES "s1ap-14.5.0.asn1")
make_version(S1AP_VERSION 14 7 0)
set(S1AP_ASN_FILES "s1ap-14.7.0.asn1")
else (${S1AP_RELEASE} STREQUAL "R15")
make_version(S1AP_VERSION 15 1 0)
set(S1AP_ASN_FILES "s1ap-15.1.0.asn1")
make_version(S1AP_VERSION 15 3 0)
set(S1AP_ASN_FILES "s1ap-15.3.0.asn1")
endif(${S1AP_RELEASE} STREQUAL "R8")
add_definitions(-DS1AP_VERSION=${S1AP_VERSION})
set(S1AP_ASN_DIR ${S1AP_DIR}/MESSAGES/ASN1/${S1AP_RELEASE})
......@@ -472,7 +472,7 @@ add_library(S1AP_ENB
# Same limitation as described in RRC/S1AP: unknown generated file list
# so we generate it at cmake time
##############
add_list1_option(X2AP_RELEASE R14 "X2AP ASN.1 grammar version" R8 R11 R12 R14 R15)
add_list1_option(X2AP_RELEASE R15 "X2AP ASN.1 grammar version" R8 R11 R12 R14 R15)
set(X2AP_DIR ${OPENAIR2_DIR}/X2AP)
if (${X2AP_RELEASE} STREQUAL "R8")
......@@ -488,8 +488,8 @@ elseif (${X2AP_RELEASE} STREQUAL "R14")
make_version(X2AP_VERSION 14 6 0)
set(X2AP_ASN_FILES x2ap-14.6.0.asn1)
elseif (${X2AP_RELEASE} STREQUAL "R15")
make_version(X2AP_VERSION 15 1 0)
set(X2AP_ASN_FILES x2ap-15.1.0.asn1)
make_version(X2AP_VERSION 15 3 0)
set(X2AP_ASN_FILES x2ap-15.3.0.asn1)
endif(${X2AP_RELEASE} STREQUAL "R8")
add_definitions(-DX2AP_VERSION=${X2AP_VERSION})
set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${X2AP_RELEASE})
......@@ -2611,16 +2611,68 @@ if (${T_TRACER})
foreach(i
#all "add_executable" definitions (except tests, rb_tool, updatefw)
lte-softmodem lte-softmodem-nos1 lte-uesoftmodem lte-uesoftmodem-nos1
nr-softmodem nr-softmodem-nos1 nr-uesoftmodem nr-uesoftmodem-nos1
dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim
pdcchsim pucchsim prachsim syncsim ulsim
ldpctest polartest
#all "add_library" definitions
ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB
oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif
oai_eth_transpro
FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA
SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL CN_UTILS
GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX
coding)
ITTI
RRC_LIB
NR_RRC_LIB
S1AP_LIB
S1AP_ENB
X2AP_LIB
params_libconfig
oai_exmimodevif
oai_usrpdevif
oai_bladerfdevif
oai_lmssdrdevif
oai_eth_transpro
oai_mobipass
tcp_bridge
tcp_bridge_oai
coding
FLPT_MSG
ASYNC_IF
FLEXRAN_AGENT
HASHTABLE
MSC
UTIL
SECU_OSA
SECU_CN
SCHED_LIB
SCHED_NR_LIB
SCHED_RU_LIB
SCHED_UE_LIB
SCHED_NR_UE_LIB
NFAPI_COMMON_LIB
NFAPI_LIB
NFAPI_PNF_LIB
NFAPI_VNF_LIB
NFAPI_USER_LIB
PHY_COMMON
PHY
PHY_UE
PHY_NR
PHY_NR_UE
PHY_RU
PHY_MEX
L2
L2_NR
L2_UE
NR_L2_UE
NR_LTE_UE_REUSE_LIB
CN_UTILS
GTPV1U
SCTP_CLIENT
UDP
LIB_NAS_UE
NB_IoT
LFDS
LFDS7
SIMU
SIMU_ETH
OPENAIR0_LIB)
if (TARGET ${i})
add_dependencies(${i} generate_T)
endif()
......
......@@ -1027,6 +1027,22 @@
<nruns>3</nruns>
</testCase>
<testCase id="015103">
<class>execution</class>
<desc>polartest test cases.</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
<pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec>
<pre_exec_args></pre_exec_args>
<main_exec> $OPENAIR_DIR/targets/bin/polartest.Rel15</main_exec>
<main_exec_args>-q -s-10 -f0</main_exec_args>
<tags>polartest.test1</tags>
<search_expr_true>BLER= 0.000000</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="015110">
<class>execution</class>
<desc>dlsim_tm4 test cases (Test 1: 10 MHz, R2.FDD (MCS 5), EVA5, -1dB),
......
......@@ -683,7 +683,7 @@ install_asn1c_from_source(){
# better to use a given commit than a branch in case the branch
# is updated and requires modifications in the source of OAI
#git checkout velichkov_s1ap_plus_option_group
git checkout 73d6b23dcec9ab36605b4af884143824392134c1
git checkout d3aed06bb2bec7df1b5c6d0333f8c7dfc5993372
autoreconf -iv
./configure
make -j`nproc`
......
......@@ -18,13 +18,17 @@ 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_int16=0;
int generate_optim_code=0;
cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
randominit(0);
crcTableInit();
//Default simulation values (Aim for iterations = 1000000.)
int itr, iterations = 1000, arguments, polarMessageType = 0; //0=PBCH, 1=DCI, -1=UCI
double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB
......@@ -36,7 +40,7 @@ int main(int argc, char *argv[]) {
double timeEncoderCumulative = 0, timeDecoderCumulative = 0;
uint8_t aggregation_level = 8, decoderListSize = 8, pathMetricAppr = 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:hqg")) != -1)
switch (arguments)
{
case 's':
......@@ -67,8 +71,20 @@ int main(int argc, char *argv[]) {
pathMetricAppr = (uint8_t) atoi(optarg);
break;
case 'q':
decoder_int16=1;
break;
case 'g':
generate_optim_code=1;
iterations=1;
SNRstart=-6.0;
SNRstop =-6.0;
decoder_int16=1;
break;
case 'h':
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n");
printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=PBCH|1=DCI|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr -q (use fixed point decoder)\n");
exit(-1);
default:
......@@ -93,10 +109,13 @@ int main(int argc, char *argv[]) {
//Logging
time_t currentTime;
time (&currentTime);
char *folderName, fileName[512], currentTimeInfo[25];
char fileName[512], currentTimeInfo[25];
char folderName[] = ".";
/*
folderName=getenv("HOME");
strcat(folderName,"/Desktop/polartestResults");
*/
#ifdef DEBUG_POLAR_TIMING
sprintf(fileName,"%s/TIMING_ListSize_%d_pmAppr_%d_Payload_%d_Itr_%d",folderName,decoderListSize,pathMetricAppr,testLength,iterations);
......@@ -107,8 +126,10 @@ int main(int argc, char *argv[]) {
strcat(fileName,currentTimeInfo);
//Create "~/Desktop/polartestResults" folder if it doesn't already exist.
/*
struct stat folder = {0};
if (stat(folderName, &folder) == -1) mkdir(folderName, S_IRWXU | S_IRWXG | S_IRWXO);
*/
FILE* logFile;
logFile = fopen(fileName, "w");
......@@ -136,6 +157,8 @@ int main(int argc, char *argv[]) {
uint8_t *encoderOutputByte = malloc(sizeof(uint8_t) * coderLength);
double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input
double *channelOutput = malloc (sizeof(double) * coderLength); //add noise
int16_t *channelOutput_int16;
if (decoder_int16 == 1) channelOutput_int16 = (int16_t*)malloc (sizeof(int16_t) * coderLength);
t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL;
nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level);
......@@ -285,6 +308,7 @@ int main(int argc, char *argv[]) {
for (int i=0; i<currentPtr->payloadBits; i++) aPrioriArray[i] = NAN;
for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) {
printf("SNR %f\n",SNR);
SNR_lin = pow(10, SNR/10);
for (itr = 1; itr <= iterations; itr++) {
......@@ -318,6 +342,15 @@ 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_int16==1) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
}
start_meas(&timeDecoder);
......@@ -327,12 +360,19 @@ int main(int argc, char *argv[]) {
NR_POLAR_DECODER_LISTSIZE,
aPrioriArray,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/
if (decoder_int16==0)
decoderState = polar_decoder_aPriori(channelOutput,
estimatedOutput,
currentPtr,
NR_POLAR_DECODER_LISTSIZE,
NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION,
aPrioriArray);
else
decoderState = polar_decoder_int16(channelOutput_int16,
estimatedOutput,
currentPtr);
stop_meas(&timeDecoder);
/*printf("testInput: [0]->0x%08x\n", testInput[0]);
printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/
......@@ -377,6 +417,9 @@ int main(int argc, char *argv[]) {
((double)bitErrorCumulative / (iterations*testLength)),
(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
if (blockErrorCumulative==0 && bitErrorCumulative==0)
break;
blockErrorCumulative = 0; bitErrorCumulative = 0;
timeEncoderCumulative = 0; timeDecoderCumulative = 0;
}
......
......@@ -255,48 +255,6 @@ unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table
return crc;
}
void nr_crc_computation(uint8_t* input, uint8_t* output, uint16_t payloadBits, uint16_t crcParityBits, uint32_t* crc256Table)
{
//Create payload in bit
uint8_t* input2 = (uint8_t*)malloc(payloadBits); //divided by 8 (in bits)
uint8_t mask = 128; // 10000000
for(uint8_t ind=0; ind<(payloadBits/8); ind++)
{
input2[ind]=0;
for(uint8_t ind2=0; ind2<8; ind2++)
{
if(input[8*ind+ind2])
{
input2[ind] = input2[ind] | mask;
}
mask= mask >> 1;
}
mask=128;
}
//crcTable256Init(poly);
unsigned int crcBits;
crcBits = crcPayload(input2, payloadBits, crc256Table);
//create crc in byte
unsigned int mask2=0x80000000; //100...
for(uint8_t ind=0; ind<crcParityBits; ind++)
{
if(crcBits & mask2)
output[ind]=1;
else
output[ind]=0;
mask2 = mask2 >> 1;
}
}
#ifdef DEBUG_CRC
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nrPolar_tools/nr_polar_defs.h"
#include "nrPolar_tools/nr_polar_pbch_defs.h"
#include "nrPolar_tools/nr_polar_uci_defs.h"
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 poly24c = 0xB2B11700; //101100101011000100010111 -> D^24...
if (messageType == 0) { //DCI
} else if (messageType == 1) { //PBCH
polarParams->n_max = NR_POLAR_PBCH_N_MAX;
polarParams->i_il = NR_POLAR_PBCH_I_IL;
polarParams->i_seg = NR_POLAR_PBCH_I_SEG;
polarParams->n_pc = NR_POLAR_PBCH_N_PC;
polarParams->n_pc_wm = NR_POLAR_PBCH_N_PC_WM;
polarParams->i_bil = NR_POLAR_PBCH_I_BIL;
polarParams->payloadBits = NR_POLAR_PBCH_PAYLOAD_BITS;
polarParams->encoderLength = NR_POLAR_PBCH_E;
polarParams->crcParityBits = NR_POLAR_PBCH_CRC_PARITY_BITS;
polarParams->K = polarParams->payloadBits + polarParams->crcParityBits; // Number of bits to encode.
polarParams->N = nr_polar_output_length(polarParams->K, polarParams->encoderLength, polarParams->n_max);
polarParams->n = log2(polarParams->N);
polarParams->crc_generator_matrix=crc24c_generator_matrix(polarParams->payloadBits);
polarParams->crc_polynomial = poly24c;
polarParams->G_N = nr_polar_kronecker_power_matrices(polarParams->n);
//polar_encoder vectors:
polarParams->nr_polar_crc = malloc(sizeof(uint8_t) * polarParams->crcParityBits);
polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K);
polarParams->nr_polar_d = malloc(sizeof(uint8_t) * polarParams->N);
//Polar Coding vectors
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
if (polarParams->payloadBits <= 11) //Ref. 38-212, Section 6.3.1.2.2
polarParams->crcParityBits = 0; //K=A
else //Ref. 38-212, Section 6.3.1.2.1
{
if (polarParams->payloadBits < 20)
polarParams->crcParityBits = NR_POLAR_PUCCH_CRC_PARITY_BITS_SHORT;
else
polarParams->crcParityBits = NR_POLAR_PUCCH_CRC_PARITY_BITS_LONG;
if (polarParams->payloadBits >= 360 && polarParams->encoderLength >= 1088)
polarParams->i_seg = NR_POLAR_PUCCH_I_SEG_LONG; // -> C=2
else
polarParams->i_seg = NR_POLAR_PUCCH_I_SEG_SHORT; // -> C=1
}
polarParams->K = polarParams->payloadBits + polarParams->crcParityBits; // Number of bits to encode.
//K_r = K/C ; C = I_seg+1
if((polarParams->K)/(polarParams->i_seg+1)>=18 && (polarParams->K)/(polarParams->i_seg+1)<=25) //Ref. 38-212, Section 6.3.1.3.1
{
polarParams->n_max = NR_POLAR_PUCCH_N_MAX;
polarParams->i_il =NR_POLAR_PUCCH_I_IL;
polarParams->n_pc = NR_POLAR_PUCCH_N_PC_SHORT;
if( (polarParams->encoderLength - polarParams->K)/(polarParams->i_seg + 1) + 3 > 192 )
polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_LONG;
else
polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_SHORT;
}
if( (polarParams->K)/(polarParams->i_seg + 1) > 30 ) //Ref. 38-212, Section 6.3.1.3.1
{
polarParams->n_max = NR_POLAR_PUCCH_N_MAX;
polarParams->i_il =NR_POLAR_PUCCH_I_IL;
polarParams->n_pc = NR_POLAR_PUCCH_N_PC_LONG;
polarParams->n_pc_wm = NR_POLAR_PUCCH_N_PC_WM_LONG;
}
polarParams->i_bil = NR_POLAR_PUCCH_I_BIL; //Ref. 38-212, Section 6.3.1.4.1
polarParams->N = nr_polar_output_length(polarParams->K, polarParams->encoderLength, polarParams->n_max);
polarParams->n = log2(polarParams->N);
if((polarParams->payloadBits) <= 19)
{
polarParams->crc_generator_matrix=crc6_generator_matrix(polarParams->payloadBits);
polarParams->crc_polynomial = poly6;
}
else
{
polarParams->crc_generator_matrix=crc11_generator_matrix(polarParams->payloadBits);
polarParams->crc_polynomial = poly11;
}
polarParams->G_N = nr_polar_kronecker_power_matrices(polarParams->n);
//polar_encoder vectors:
polarParams->nr_polar_crc = malloc(sizeof(uint8_t) * polarParams->crcParityBits);
polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K);
polarParams->nr_polar_d = malloc(sizeof(uint8_t) * polarParams->N);
//Polar Coding vectors
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;
polarParams->crc256Table = malloc(sizeof(uint32_t)*256);
crcTable256Init(polarParams->crc_polynomial, polarParams->crc256Table);
polarParams->Q_0_Nminus1 = nr_polar_sequence_pattern(polarParams->n);
polarParams->interleaving_pattern = malloc(sizeof(uint16_t) * polarParams->K);
nr_polar_interleaving_pattern(polarParams->K, polarParams->i_il, polarParams->interleaving_pattern);
polarParams->rate_matching_pattern = malloc(sizeof(uint16_t) * polarParams->encoderLength);
uint16_t *J = malloc(sizeof(uint16_t) * polarParams->N);
nr_polar_rate_matching_pattern(polarParams->rate_matching_pattern, J,
nr_polar_subblock_interleaver_pattern, polarParams->K, polarParams->N, polarParams->encoderLength);
polarParams->information_bit_pattern = malloc(sizeof(uint8_t) * polarParams->N);
polarParams->Q_I_N = malloc(sizeof(int16_t) * (polarParams->K + polarParams->n_pc));
polarParams->Q_F_N = malloc(sizeof(int16_t) * (polarParams->N+1)); // Last element shows the final array index assigned a value.
polarParams->Q_PC_N = malloc(sizeof(int16_t) * (polarParams->n_pc));
for (int i=0; i<=polarParams->N; i++) polarParams->Q_F_N[i] = -1; // Empty array.
nr_polar_info_bit_pattern(polarParams->information_bit_pattern,
polarParams->Q_I_N, polarParams->Q_F_N, J, polarParams->Q_0_Nminus1,
polarParams->K, polarParams->N, polarParams->encoderLength, polarParams->n_pc);
polarParams->channel_interleaver_pattern = malloc(sizeof(uint16_t) * polarParams->encoderLength);
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);
}
......@@ -21,132 +21,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
/*
// ----- New implementation ----
uint32_t poly6 = 0x84000000; // 10000100000... -> D^6+D^5+1
uint32_t poly11 = 0xc4200000; //11000100001000... -> D^11+D^10+D^9+D^5+1
uint32_t poly16 = 0x10210000; //00100000010000100... - > 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...
//static unsigned int crc256Table[256];
void nr_crc_computation(uint8_t* input, uint8_t* output, uint16_t payloadBits, uint16_t crcParityBits, uint32_t* crc256Table)
{
//Create payload in bit
uint8_t* input2 = (uint8_t*)malloc(payloadBits); //divided by 8 (in bits)
uint8_t mask = 128; // 10000000
for(uint8_t ind=0; ind<(payloadBits/8); ind++)
{
input2[ind]=0;
for(uint8_t ind2=0; ind2<8; ind2++)
{
if(input[8*ind+ind2])
{
input2[ind] = input2[ind] | mask;
}
mask= mask >> 1;
}
mask=128;
}
//crcTable256Init(poly);
unsigned int crcBits;
crcBits = crcPayload(input2, payloadBits, crc256Table);
//create crc in byte
unsigned int mask2=0x80000000; //100...
output = (uint8_t*)malloc(sizeof(uint8_t)*crcParityBits);
for(uint8_t ind=0; ind<crcParityBits; ind++)
{
if(crcBits & mask2)
output[ind]=1;
else
output[ind]=0;
mask2 = mask2 >> 1;
}
}
unsigned int crcbit (unsigned char* inputptr, int octetlen, unsigned int poly)
{
unsigned int i, crc = 0, c;
while (octetlen-- > 0) {
c = (*inputptr++) << 24;
for (i = 8; i != 0; i--) {
if ((1 << 31) & (c ^ crc))
crc = (crc << 1) ^ poly;
else
crc <<= 1;
c <<= 1;
}
}
return crc;
}
void crcTableInit (void)
{
unsigned char c = 0;
do {
crc6Table[c] = crcbit(&c, 1, poly6);
crc11Table[c]= crcbit(&c, 1, poly11);
crc16Table[c] =crcbit(&c, 1, poly16);
crc24aTable[c]=crcbit(&c, 1, poly24a);
crc24bTable[c]=crcbit(&c, 1, poly24b);
crc24cTable[c]=crcbit(&c, 1, poly24c);
} while (++c);
}
void crcTable256Init (uint32_t poly, uint32_t* crc256Table)
{
unsigned char c = 0;
// crc256Table = malloc(sizeof(uint32_t)*256);
do {
crc256Table[c] = crcbit(&c, 1, poly);
// crc6Table[c] = crcbit(&c, 1, poly6);
// crc11Table[c]= crcbit(&c, 1, poly11);
// crc16Table[c] =crcbit(&c, 1, poly16);
// crc24aTable[c]=crcbit(&c, 1, poly24a);
// crc24bTable[c]=crcbit(&c, 1, poly24b);
// crc24cTable[c]=crcbit(&c, 1, poly24c);
} while (++c);
//return crc256Table;
}
unsigned int crcPayload(unsigned char * inptr, int bitlen, uint32_t* crc256Table)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen/8; // Change in bytes
resbit = (bitlen % 8);
while (octetlen-- > 0)
{
crc = (crc << 8) ^ crc256Table[(*inptr++) ^ (crc >> 24)];
}
if (resbit > 0)
{
crc = (crc << resbit) ^ crc256Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
}
return crc;
}
*/
// ----- Old implementation ----
uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits){
......
......@@ -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
*/
......@@ -38,6 +38,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
int8_t polar_decoder(
double *input,
uint8_t *out,
......@@ -285,7 +286,6 @@ int8_t polar_decoder_aPriori(double *input,
uint8_t pathMetricAppr,
double *aPrioriPayload)
{
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
......@@ -355,6 +355,7 @@ int8_t polar_decoder_aPriori(double *input,
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
......@@ -528,6 +529,7 @@ int8_t polar_decoder_aPriori(double *input,
*/
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
}
......@@ -1034,3 +1036,42 @@ int8_t polar_decoder_dci(double *input,
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
}
int8_t polar_decoder_int16(int16_t *input,
uint8_t *out,
t_nrPolar_params *polarParams)
{
int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N);
nr_polar_rate_matching_int16(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);
/*
* SCL polar decoder.
*/
generic_polar_decoder(polarParams,polarParams->tree.root);
//Extract the information bits (û to ĉ)
nr_polar_info_bit_extraction(polarParams->nr_polar_U, polarParams->nr_polar_CPrime, polarParams->information_bit_pattern, polarParams->N);
//Deinterleaving (ĉ to b)
nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K);
//Remove the CRC (â)
for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j];
nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out);
return(0);
}
......@@ -31,6 +31,10 @@
*/
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/sse_intrin.h"
#include "PHY/impl_defs_top.h"
//#define DEBUG_NEW_IMPL
void updateLLR(double ***llr,
uint8_t **llrU,
......@@ -56,8 +60,9 @@ void updateLLR(double ***llr,
computeLLR(llr, row, col, i, offset, approximation);
}
}
llrU[row][col]=1;
// printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]);
}
void updateBit(uint8_t ***bit,
......@@ -68,6 +73,7 @@ void updateBit(uint8_t ***bit,
uint16_t xlen,
uint8_t ylen)
{
uint16_t offset = ( xlen/(pow(2,(ylen-col))) );
for (uint8_t i=0; i<listSize; i++) {
......@@ -101,6 +107,7 @@ void updatePathMetric(double *pathMetric,
}
}
void updatePathMetric2(double *pathMetric,
double ***llr,
uint8_t listSize,
......@@ -110,6 +117,7 @@ void updatePathMetric2(double *pathMetric,
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++) {
......@@ -132,7 +140,9 @@ void updatePathMetric2(double *pathMetric,
free(tempPM);
}
}
void computeLLR(double ***llr,
uint16_t row,
......@@ -152,6 +162,7 @@ void computeLLR(double ***llr,
llr[row][col][i] = log((exp(a + b) + 1) / (exp(a) + exp(b)));
}
}
void updateCrcChecksum(uint8_t **crcChecksum,
......@@ -179,3 +190,347 @@ void updateCrcChecksum2(uint8_t **crcChecksum,
}
}
}
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 build_decoder_tree(t_nrPolar_params *pp) {
pp->tree.num_nodes=0;
pp->tree.root = add_nodes(pp->n,0,pp);
}
#if defined(__arm__) || defined(__aarch64__)
// translate 1-1 SIMD functions from SSE to NEON
#define __m128i int16x8_t
#define __m64 int8x8_t
#define _mm_abs_epi16(a) vabsq_s16(a)
#define _mm_min_epi16(a,b) vminq_s16(a,b)
#define _mm_subs_epi16(a,b) vsubq_s16(a,b)
#define _mm_abs_pi16(a) vabs_s16(a)
#define _mm_min_pi16(a,b) vmin_s16(a,b)
#define _mm_subs_pi16(a,b) vsub_s16(a,b)
#endif
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;
// printf("avx2len %d\n",avx2len);
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_sign_epi16(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_sign_epi16(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_sign_pi16(a64,b64));
}
else
#else
int sse4mod = (node->Nv/2)&7;
int sse4len = node->Nv/2/8;
#if defined(__arm__) || defined(__aarch64__)
int16x8_t signatimesb,comp1,comp2,negminabs128;
int16x8_t zero=vdupq_n_s16(0);
#endif
if (sse4mod == 0) {
for (int i=0;i<sse4len;i++) {
__m128i a128,b128,absa128,absb128,minabs128;
int sse4len = node->Nv/2/8;
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);
#if defined(__arm__) || defined(__aarch64__)
// unfortunately no direct equivalent to _mm_sign_epi16
signatimesb=vxorrq_s16(a128,b128);
comp1=vcltq_s16(signatimesb,zero);
comp2=vcgeq_s16(signatimesb,zero);
negminabs128=vnegq_s16(minabs128);
*((__m128i*)alpha_l) =vorrq_s16(vandq_s16(minabs128,comp0),vandq_s16(negminabs128,comp1));
#else
*((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_sign_epi16(a128,b128));
#endif
}
}
else if (sse4mod == 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);
#if defined(__arm__) || defined(__aarch64__)
AssertFatal(1==0,"Need to do this still for ARM\n");
#else
*((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_sign_epi16(a64,b64));
#endif
}
else
#endif
{ // equvalent scalar code to above, activated only on non x86/ARM architectures
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;
// printf("alphal[%d] %d (%d,%d)\n",i,alpha_l[i],a,b);
}
}
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 if (avx2mod == 4) {
((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__m64 *)alpha_v)[0],((__m64 *)betal)[0]));
}
else
#else
int sse4mod = (node->Nv/2)&7;
if (sse4mod == 0) {
int sse4len = node->Nv/2/8;
for (int i=0;i<sse4len;i++) {
#if defined(__arm__) || defined(__aarch64__)
((int16x8_t *)alpha_r)[0] = vsubq_s16(((int16x8_t *)alpha_v)[1],vmulq_epi16(((int16x8_t *)alpha_v)[0],((int16x8_t *)betal)[0]));
#else
((__m128i *)alpha_r)[0] = _mm_subs_epi16(((__m128i *)alpha_v)[1],_mm_sign_epi16(((__m128i *)alpha_v)[0],((__m128i *)betal)[0]));
#endif
}
}
else if (sse4mod == 4) {
#if defined(__arm__) || defined(__aarch64__)
((int16x4_t *)alpha_r)[0] = vsub_s16(((int16x4_t *)alpha_v)[1],vmul_epi16(((int16x4_t *)alpha_v)[0],((int16x4_t *)betal)[0]));
#else
((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__64 *)alpha_v)[0],((__m64 *)betal)[0]));
#endif
}
else
#endif
{// equvalent scalar code to above, activated only on non x86/ARM architectures
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)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0]);
#endif
}
}
}
int16_t all1[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;
register __m256i allones=*((__m256i*)all1);
if (avx2mod == 0) {
int avx2len = node->Nv/2/16;
for (int i=0;i<avx2len;i++) {
((__m256i*)betav)[i] = _mm256_or_si256(_mm256_cmpeq_epi16(((__m256i*)betar)[i],
((__m256i*)betal)[i]),allones);
}
}
else if (avx2mod == 8) {
((__m128i*)betav)[0] = _mm_or_si128(_mm_cmpeq_epi16(((__m128i*)betar)[0],
((__m128i*)betal)[0]),*((__m128i*)all1));
}
else if (avx2mod == 4) {
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi16(((__m64*)betar)[0],
((__m64*)betal)[0]),*((__m64*)all1));
}
else
#else
int avx2mod = (node->Nv/2)&15;
if (ssr4mod == 0) {
int ssr4len = node->Nv/2/8;
register __m128i allones=*((__m128i*)all1);
for (int i=0;i<sse4len;i++) {
((__m256i*)betav)[i] = _mm_or_si128(_mm_cmpeq_epi16(((__m128i*)betar)[i],
((__m128i*)betal)[i]),allones));
}
}
else if (sse4mod == 4) {
((__m64*)betav)[0] = _mm_or_si64(_mm_cmpeq_pi16(((__m64*)betar)[0],
((__m64*)betal)[0]),*((__m64*)all1));
}
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);
}
......@@ -56,6 +56,27 @@
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_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 {
//messageType: 0=PBCH, 1=DCI, -1=UCI
int idx; //idx = (messageType * messageLength * aggregation_prime);
......@@ -89,7 +110,7 @@ struct nrPolar_params {
uint8_t **crc_generator_matrix; //G_P
uint8_t **G_N;
uint32_t* crc256Table;
uint8_t **extended_crc_generator_matrix;
//lowercase: bits, Uppercase: Bits stored in bytes
//polar_encoder vectors
uint8_t *nr_polar_crc;
......@@ -103,6 +124,8 @@ struct nrPolar_params {
uint8_t *nr_polar_CPrime;
uint8_t *nr_polar_B;
uint8_t *nr_polar_U;
decoder_tree_t tree;
} __attribute__ ((__packed__));
typedef struct nrPolar_params t_nrPolar_params;
typedef t_nrPolar_params *t_nrPolar_paramsPtr;
......@@ -151,6 +174,8 @@ int8_t polar_decoder_dci(double *input,
uint8_t pathMetricAppr,
uint16_t n_RNTI);
void generic_polar_decoder(t_nrPolar_params *,decoder_node_t *);
void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
int8_t messageType,
uint16_t messageLength,
......@@ -196,6 +221,8 @@ void nr_polar_rate_matching(double *input,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching_int16(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_);
......
......@@ -111,6 +111,32 @@ double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen)
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) {
uint8_t **output;
int i, j;
......@@ -136,6 +162,18 @@ uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) {
return output;
}
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_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
......@@ -153,13 +191,10 @@ void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) {
free(input);
}
void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
int i, j;
void nr_free_double_2D_array(double **input, uint16_t xlen) {
int i;
for (i = 0; i < xlen; i++) {
for (j = 0; j < ylen; j++) {
free(input[i][j]);
}
free(input[i]);
}
free(input);
......@@ -167,13 +202,38 @@ void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) {
// Modified Bubble Sort.
void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) {
uint8_t swaps;
int swaps;
double temp;
uint8_t tempInd;
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;
}
}
void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len) {
int swaps;
int16_t temp;
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];
......
......@@ -313,3 +313,25 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16
}
}
void nr_polar_rate_matching_int16(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];
}
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <math.h>
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P_i_, uint16_t K, uint16_t N, uint16_t E){
uint8_t i;
uint16_t *d, *y, ind;
d = (uint16_t *)malloc(sizeof(uint16_t) * N);
y = (uint16_t *)malloc(sizeof(uint16_t) * N);
for (int m=0; m<=N-1; m++) d[m]=m;
for (int m=0; m<=N-1; m++){
i=floor((32*m)/N);
J[m] = (P_i_[i]*(N/32)) + (m%(N/32));
y[m] = d[J[m]];
}
if (E>=N) { //repetition
for (int k=0; k<=E-1; k++) {
ind = (k%N);
rmp[k]=y[ind];
}
} else {
if ( (K/(double)E) <= (7.0/16) ) { //puncturing
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k+N-E];
}
} else { //shortening
for (int k=0; k<=E-1; k++) {
rmp[k]=y[k];
}
}
}
free(d);
free(y);
}
void nr_polar_rate_matching(double *input, double *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];
}
}
}
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];
}
}
}
......@@ -147,6 +147,9 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams,
free(J);
build_decoder_tree(newPolarInitNode);
printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes);
} else {
AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created");
}
......
......@@ -72,6 +72,7 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms)
init_dfts();
crcTableInit();
phy_generate_viterbi_tables_lte();
......
......@@ -115,6 +115,10 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
);*/
LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id);
crcTableInit();
init_dfts();
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
// Polar encoder init for PBCH
......
......@@ -947,6 +947,8 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue)
crcTableInit();
init_dfts();
ccodedot11_init();
ccodedot11_init_inv();
......
/*
* 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/LTE_TRANSPORT/dlsch_decoding.c
* \brief Top-level routines for decoding Turbo-coded (DLSCH) transport channels from 36-212, V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
//#include "defs.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/extern.h"
#include "SCHED/extern.h"
#include "SIMULATION/TOOLS/defs.h"
//#define DEBUG_DLSCH_DECODING
//#define UE_DEBUG_TRACE 1
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
{
int i,r;
if (dlsch) {
for (i=0; i<dlsch->Mdlharq; i++) {
if (dlsch->harq_processes[i]) {
if (dlsch->harq_processes[i]->b) {
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
dlsch->harq_processes[i]->b = NULL;
}
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) {
free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
dlsch->harq_processes[i]->c[r] = NULL;
}
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++)
if (dlsch->harq_processes[i]->d[r]) {
free16(dlsch->harq_processes[i]->d[r],((3*8*6144)+12+96)*sizeof(short));
dlsch->harq_processes[i]->d[r] = NULL;
}
free16(dlsch->harq_processes[i],sizeof(LTE_DL_UE_HARQ_t));
dlsch->harq_processes[i] = NULL;
}
}
free16(dlsch,sizeof(LTE_UE_DLSCH_t));
dlsch = NULL;
}
}
LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag)
{
LTE_UE_DLSCH_t *dlsch;
uint8_t exit_flag = 0,i,r;
unsigned char bw_scaling =1;
switch (N_RB_DL) {
case 6:
bw_scaling =16;
break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
dlsch = (LTE_UE_DLSCH_t *)malloc16(sizeof(LTE_UE_DLSCH_t));
if (dlsch) {
memset(dlsch,0,sizeof(LTE_UE_DLSCH_t));
dlsch->Kmimo = Kmimo;
dlsch->Mdlharq = Mdlharq;
dlsch->Nsoft = Nsoft;
dlsch->max_turbo_iterations = max_turbo_iterations;
for (i=0; i<Mdlharq; i++) {
// printf("new_ue_dlsch: Harq process %d\n",i);
dlsch->harq_processes[i] = (LTE_DL_UE_HARQ_t *)malloc16(sizeof(LTE_DL_UE_HARQ_t));
if (dlsch->harq_processes[i]) {
memset(dlsch->harq_processes[i],0,sizeof(LTE_DL_UE_HARQ_t));
dlsch->harq_processes[i]->first_tx=1;
dlsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
if (dlsch->harq_processes[i]->b)
memset(dlsch->harq_processes[i]->b,0,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling);
else
exit_flag=3;
if (abstraction_flag == 0) {
for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) {
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768);
if (dlsch->harq_processes[i]->c[r])
memset(dlsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+ 768);
else
exit_flag=2;
dlsch->harq_processes[i]->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short));
if (dlsch->harq_processes[i]->d[r])
memset(dlsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short));
else
exit_flag=2;
}
}
} else {
exit_flag=1;
}
}
if (exit_flag==0)
return(dlsch);
}
printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag);
free_ue_dlsch(dlsch);
return(NULL);
}
uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
short *dlsch_llr,
LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_DLSCH_t *dlsch,
LTE_DL_UE_HARQ_t *harq_process,
uint32_t frame,
uint8_t subframe,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag)
{
#if UE_TIMING_TRACE
time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
#endif
uint32_t A,E;
uint32_t G;
uint32_t ret,offset;
uint16_t iind;
// uint8_t dummy_channel_output[(3*8*block_length)+12];
short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0;
uint8_t crc_type;
#ifdef DEBUG_DLSCH_DECODING
uint16_t i;
#endif
//#ifdef __AVX2__
#if 0
int Kr_last,skipped_last=0;
uint8_t (*tc_2cw)(int16_t *y,
int16_t *y2,
uint8_t *,
uint8_t *,
uint16_t,
uint16_t,
uint16_t,
uint8_t,
uint8_t,
uint8_t,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *,
time_stats_t *);
#endif
decoder_if_t tc;
if (!dlsch_llr) {
printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
return(dlsch->max_turbo_iterations);
}
if (!harq_process) {
printf("dlsch_decoding.c: NULL harq_process pointer\n");
return(dlsch->max_turbo_iterations);
}
if (!frame_parms) {
printf("dlsch_decoding.c: NULL frame_parms pointer\n");
return(dlsch->max_turbo_iterations);
}
if (subframe>9) {
printf("dlsch_decoding.c: Illegal subframe index %d\n",subframe);
return(dlsch->max_turbo_iterations);
}
if (dlsch->harq_ack[subframe].ack != 2) {
LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n",
phy_vars_ue->Mod_id, subframe, dlsch->harq_ack[subframe].ack);
}
if (llr8_flag == 0) {
//#ifdef __AVX2__
#if 0
tc_2cw = phy_threegpplte_turbo_decoder16avx2;
#endif
tc = decoder16;
}
else
{
AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n",
harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
tc = decoder8;
}
// nb_rb = dlsch->nb_rb;
/*
if (nb_rb > frame_parms->N_RB_DL) {
printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
return(max_turbo_iterations);
}*/
/*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
if (harq_pid >= 8) {
printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
return(max_turbo_iterations);
}
*/
harq_process->trials[harq_process->round]++;
A = harq_process->TBS; //2072 for QPSK 1/3
ret = dlsch->max_turbo_iterations;
G = harq_process->G;
//get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);
// printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
if (harq_process->round == 0) {
// This is a new packet, so compute quantities regarding segmentation
harq_process->B = A+24;
lte_segmentation(NULL,
NULL,
harq_process->B,
&harq_process->C,
&harq_process->Cplus,
&harq_process->Cminus,
&harq_process->Kplus,
&harq_process->Kminus,
&harq_process->F);
// CLEAR LLR's HERE for first packet in process
}
/*
else {
printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
return(max_turbo_iterations);
}
*/
err_flag = 0;
r_offset = 0;
unsigned char bw_scaling =1;
switch (frame_parms->N_RB_DL) {
case 6:
bw_scaling =16;
break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) {
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling);
return((1+dlsch->max_turbo_iterations));
}
#ifdef DEBUG_DLSCH_DECODING
printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
#endif
opp_enabled=1;
for (r=0; r<harq_process->C; r++) {
// Get Turbo interleaver parameters
if (r<harq_process->Cminus)
Kr = harq_process->Kminus;
else
Kr = harq_process->Kplus;
Kr_bytes = Kr>>3;
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
printf("dlsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
return(dlsch->max_turbo_iterations);
}
#ifdef DEBUG_DLSCH_DECODING
printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? harq_process->F : 0);
#endif
#if UE_TIMING_TRACE
start_meas(dlsch_rate_unmatching_stats);
#endif
memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
harq_process->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
(uint8_t*) &dummy_w[r][0],
(r==0) ? harq_process->F : 0);
#ifdef DEBUG_DLSCH_DECODING
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
harq_process->TBS,
harq_process->Qm,
harq_process->nb_rb,
harq_process->Nl,
harq_process->rvidx,
harq_process->round);
#endif
#ifdef DEBUG_DLSCH_DECODING
printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
#endif
if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
G,
harq_process->w[r],
(uint8_t*)&dummy_w[r][0],
dlsch_llr+r_offset,
harq_process->C,
dlsch->Nsoft,
dlsch->Mdlharq,
dlsch->Kmimo,
harq_process->rvidx,
(harq_process->round==0)?1:0,
harq_process->Qm,
harq_process->Nl,
r,
&E)==-1) {
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
return(dlsch->max_turbo_iterations);
} else
{
#if UE_TIMING_TRACE
stop_meas(dlsch_rate_unmatching_stats);
#endif
}
r_offset += E;
/*
printf("Subblock deinterleaving, d %p w %p\n",
harq_process->d[r],
harq_process->w);
*/
#if UE_TIMING_TRACE
start_meas(dlsch_deinterleaving_stats);
#endif
sub_block_deinterleaving_turbo(4+Kr,
&harq_process->d[r][96],
harq_process->w[r]);
#if UE_TIMING_TRACE
stop_meas(dlsch_deinterleaving_stats);
#endif
#ifdef DEBUG_DLSCH_DECODING
/*
if (r==0) {
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
}
printf("decoder input(segment %d) :",r);
int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
printf("%d : %d\n",i,harq_process->d[r][96+i]);
printf("\n");*/
#endif
// printf("Clearing c, %p\n",harq_process->c[r]);
memset(harq_process->c[r],0,Kr_bytes);
// printf("done\n");
if (harq_process->C == 1)
crc_type = CRC24_A;
else
crc_type = CRC24_B;
/*
printf("decoder input(segment %d)\n",r);
for (i=0;i<(3*8*Kr_bytes)+12;i++)
if ((harq_process->d[r][96+i]>7) ||
(harq_process->d[r][96+i] < -8))
printf("%d : %d\n",i,harq_process->d[r][96+i]);
printf("\n");
*/
//#ifndef __AVX2__
#if 1
if (err_flag == 0) {
/*
LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations);
*/
if (llr8_flag) {
AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
}
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
ret = tc
(&harq_process->d[r][96],
NULL,
harq_process->c[r],
NULL,
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
dlsch->max_turbo_iterations,
crc_type,
(r==0) ? harq_process->F : 0,
&phy_vars_ue->dlsch_tc_init_stats,
&phy_vars_ue->dlsch_tc_alpha_stats,
&phy_vars_ue->dlsch_tc_beta_stats,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
#endif
}
#else
if ((harq_process->C == 1) ||
((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
ret = tc
(&harq_process->d[r][96],
harq_process->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
dlsch->max_turbo_iterations,
crc_type,
(r==0) ? harq_process->F : 0,
&phy_vars_ue->dlsch_tc_init_stats,
&phy_vars_ue->dlsch_tc_alpha_stats,
&phy_vars_ue->dlsch_tc_beta_stats,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
#endif
// printf("single decode, exit\n");
// exit(-1);
}
else {
// we can merge code segments
if ((skipped_last == 0) && (r<harq_process->C-1)) {
skipped_last = 1;
Kr_last = Kr;
}
else {
skipped_last=0;
if (Kr_last == Kr) { // decode 2 code segments with AVX2 version
#ifdef DEBUG_DLSCH_DECODING
printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]);
#endif
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
#ifdef DEBUG_DLSCH_DECODING
printf("double decoding segments %d,%d (%p,%p)\n",r-1,r,&harq_process->d[r-1][96],&harq_process->d[r][96]);
#endif
ret = tc_2cw
(&harq_process->d[r-1][96],
&harq_process->d[r][96],
harq_process->c[r-1],
harq_process->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
dlsch->max_turbo_iterations,
crc_type,
(r==0) ? harq_process->F : 0,
&phy_vars_ue->dlsch_tc_init_stats,
&phy_vars_ue->dlsch_tc_alpha_stats,
&phy_vars_ue->dlsch_tc_beta_stats,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
/*
ret = tc
(&harq_process->d[r-1][96],
harq_process->c[r-1],
Kr_last,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
dlsch->max_turbo_iterations,
crc_type,
(r==0) ? harq_process->F : 0,
&phy_vars_ue->dlsch_tc_init_stats,
&phy_vars_ue->dlsch_tc_alpha_stats,
&phy_vars_ue->dlsch_tc_beta_stats,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
exit(-1);*/
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
#endif
}
else { // Kr_last != Kr
#if UE_TIMING_TRACE
start_meas(dlsch_turbo_decoding_stats);
#endif
ret = tc
(&harq_process->d[r-1][96],
harq_process->c[r-1],
Kr_last,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
dlsch->max_turbo_iterations,
crc_type,
(r==0) ? harq_process->F : 0,
&phy_vars_ue->dlsch_tc_init_stats,
&phy_vars_ue->dlsch_tc_alpha_stats,
&phy_vars_ue->dlsch_tc_beta_stats,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
start_meas(dlsch_turbo_decoding_stats);
#endif
ret = tc
(&harq_process->d[r][96],
harq_process->c[r],
Kr,
f1f2mat_old[iind*2],
f1f2mat_old[(iind*2)+1],
dlsch->max_turbo_iterations,
crc_type,
(r==0) ? harq_process->F : 0,
&phy_vars_ue->dlsch_tc_init_stats,
&phy_vars_ue->dlsch_tc_alpha_stats,
&phy_vars_ue->dlsch_tc_beta_stats,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
/*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n",
harq_process->C,
r,
dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
#endif
}
}
}
#endif
if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
err_flag = 1;
}
}
int32_t frame_rx_prev = frame;
int32_t subframe_rx_prev = subframe - 1;
if (subframe_rx_prev < 0) {
frame_rx_prev--;
subframe_rx_prev += 10;
}
frame_rx_prev = frame_rx_prev%1024;
if (err_flag == 1) {
#if UE_DEBUG_TRACE
LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
#endif
dlsch->harq_ack[subframe].ack = 0;
dlsch->harq_ack[subframe].harq_id = harq_pid;
dlsch->harq_ack[subframe].send_harq_status = 1;
harq_process->errors[harq_process->round]++;
harq_process->round++;
// printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
if (harq_process->round >= dlsch->Mdlharq) {
harq_process->status = SCH_IDLE;
harq_process->round = 0;
}
if(is_crnti)
{
LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
}
return((1+dlsch->max_turbo_iterations));
} else {
#if UE_DEBUG_TRACE
LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n",
phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
#endif
harq_process->status = SCH_IDLE;
harq_process->round = 0;
dlsch->harq_ack[subframe].ack = 1;
dlsch->harq_ack[subframe].harq_id = harq_pid;
dlsch->harq_ack[subframe].send_harq_status = 1;
//LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
// phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs);
if(is_crnti)
{
LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
}
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
}
// Reassembly of Transport block here
offset = 0;
/*
printf("harq_pid %d\n",harq_pid);
printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
printf("C %d\n",harq_process->C);
*/
for (r=0; r<harq_process->C; r++) {
if (r<harq_process->Cminus)
Kr = harq_process->Kminus;
else
Kr = harq_process->Kplus;
Kr_bytes = Kr>>3;
// printf("Segment %d : Kr= %d bytes\n",r,Kr_bytes);
if (r==0) {
memcpy(harq_process->b,
&harq_process->c[0][(harq_process->F>>3)],
Kr_bytes - (harq_process->F>>3)- ((harq_process->C>1)?3:0));
offset = Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0);
// printf("copied %d bytes to b sequence (harq_pid %d)\n",
// Kr_bytes - (harq_process->F>>3),harq_pid);
// printf("b[0] = %x,c[%d] = %x\n",
// harq_process->b[0],
// harq_process->F>>3,
// harq_process->c[0][(harq_process->F>>3)]);
} else {
memcpy(harq_process->b+offset,
harq_process->c[r],
Kr_bytes- ((harq_process->C>1)?3:0));
offset += (Kr_bytes - ((harq_process->C>1)?3:0));
}
}
dlsch->last_iteration_cnt = ret;
return(ret);
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* 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/LTE_TRANSPORT/drs_modulation.c
* \brief Top-level routines for generating the Demodulation Reference Signals from 36-211, V8.6 2009-03
* \author R. Knopp, F. Kaltenberger, A. Bhamri
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/sse_intrin.h"
//#define DEBUG_DRS
int generate_drs_pusch(PHY_VARS_UE *ue,
UE_rxtx_proc_t *proc,
uint8_t eNB_id,
short amp,
unsigned int subframe,
unsigned int first_rb,
unsigned int nb_rb,
uint8_t ant)
{
uint16_t k,l,Msc_RS,Msc_RS_idx,rb,drs_offset;
uint16_t * Msc_idx_ptr;
int subframe_offset,re_offset,symbol_offset;
//uint32_t phase_shift; // phase shift for cyclic delay in DM RS
//uint8_t alpha_ind;
int16_t alpha_re[12] = {32767, 28377, 16383, 0,-16384, -28378,-32768,-28378,-16384, -1, 16383, 28377};
int16_t alpha_im[12] = {0, 16383, 28377, 32767, 28377, 16383, 0,-16384,-28378,-32768,-28378,-16384};
uint8_t cyclic_shift,cyclic_shift0,cyclic_shift1;
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int32_t *txdataF = ue->common_vars.txdataF[ant];
uint32_t u,v,alpha_ind;
uint32_t u0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1];
uint32_t u1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)];
uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
int32_t ref_re,ref_im;
uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_tx,subframe);
cyclic_shift0 = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 +
frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]+
((ue->ulsch[0]->cooperation_flag==2)?10:0)+
ant*6) % 12;
// printf("PUSCH.cyclicShift %d, n_DMRS2 %d, nPRS %d\n",frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,ue->ulsch[eNB_id]->n_DMRS2,ue->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]);
cyclic_shift1 = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 +
frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[(subframe<<1)+1]+
((ue->ulsch[0]->cooperation_flag==2)?10:0)+
ant*6) % 12;
// cyclic_shift0 = 0;
// cyclic_shift1 = 0;
Msc_RS = 12*nb_rb;
Msc_idx_ptr = (uint16_t*) bsearch(&Msc_RS, dftsizes, 33, sizeof(uint16_t), compareints);
if (Msc_idx_ptr)
Msc_RS_idx = Msc_idx_ptr - dftsizes;
else {
LOG_I(PHY,"generate_drs_pusch: index for Msc_RS=%d not found\n",Msc_RS);
return(-1);
}
for (l = (3 - frame_parms->Ncp),u=u0,v=v0,cyclic_shift=cyclic_shift0;
l<frame_parms->symbols_per_tti;
l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) {
drs_offset = 0;
#ifdef DEBUG_DRS
printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d, u=%d,v=%d\n",Msc_RS, Msc_RS_idx,u,v);
#endif
re_offset = frame_parms->first_carrier_offset;
subframe_offset = subframe*frame_parms->symbols_per_tti*frame_parms->ofdm_symbol_size;
symbol_offset = subframe_offset + frame_parms->ofdm_symbol_size*l;
#ifdef DEBUG_DRS
printf("generate_drs_pusch: symbol_offset %d, subframe offset %d, cyclic shift %d\n",symbol_offset,subframe_offset,cyclic_shift);
#endif
alpha_ind = 0;
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
if ((rb >= first_rb) && (rb<(first_rb+nb_rb))) {
#ifdef DEBUG_DRS
printf("generate_drs_pusch: doing RB %d, re_offset=%d, drs_offset=%d,cyclic shift %d\n",rb,re_offset,drs_offset,cyclic_shift);
#endif
for (k=0; k<12; k++) {
ref_re = (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][drs_offset<<1];
ref_im = (int32_t) ul_ref_sigs[u][v][Msc_RS_idx][(drs_offset<<1)+1];
((int16_t*) txdataF)[2*(symbol_offset + re_offset)] = (int16_t) (((ref_re*alpha_re[alpha_ind]) -
(ref_im*alpha_im[alpha_ind]))>>15);
((int16_t*) txdataF)[2*(symbol_offset + re_offset)+1] = (int16_t) (((ref_re*alpha_im[alpha_ind]) +
(ref_im*alpha_re[alpha_ind]))>>15);
((short*) txdataF)[2*(symbol_offset + re_offset)] = (short) ((((short*) txdataF)[2*(symbol_offset + re_offset)]*(int32_t)amp)>>15);
((short*) txdataF)[2*(symbol_offset + re_offset)+1] = (short) ((((short*) txdataF)[2*(symbol_offset + re_offset)+1]*(int32_t)amp)>>15);
alpha_ind = (alpha_ind + cyclic_shift);
if (alpha_ind > 11)
alpha_ind-=12;
#ifdef DEBUG_DRS
printf("symbol_offset %d, alpha_ind %d , re_offset %d : (%d,%d)\n",
symbol_offset,
alpha_ind,
re_offset,
((short*) txdataF)[2*(symbol_offset + re_offset)],
((short*) txdataF)[2*(symbol_offset + re_offset)+1]);
#endif // DEBUG_DRS
re_offset++;
drs_offset++;
if (re_offset >= frame_parms->ofdm_symbol_size)
re_offset = 0;
}
} else {
re_offset+=12; // go to next RB
// check if we crossed the symbol boundary and skip DC
if (re_offset >= frame_parms->ofdm_symbol_size) {
if (frame_parms->N_RB_DL&1) // odd number of RBs
re_offset=6;
else // even number of RBs (doesn't straddle DC)
re_offset=0;
}
}
}
}
return(0);
}
/*
* 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/LTE_TRANSPORT/ulsch_coding.c
* \brief Top-level routines for coding the ULSCH transport channel as described in 36.212 V8.6 2009-03
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/defs.h"
#include "defs.h"
#include "extern.h"
#include "SIMULATION/ETH_TRANSPORT/extern.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_ULSCH_CODING
//#define DEBUG_ULSCH_FREE 1
/*
#define is_not_pilot(pilots,first_pilot,re) (pilots==0) || \
((pilots==1)&&(first_pilot==1)&&(((re>2)&&(re<6))||((re>8)&&(re<12)))) || \
((pilots==1)&&(first_pilot==0)&&(((re<3))||((re>5)&&(re<9)))) \
*/
#define is_not_pilot(pilots,first_pilot,re) (1)
void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch)
{
int i;
int r;
if (ulsch) {
#ifdef DEBUG_ULSCH_FREE
printf("Freeing ulsch %p\n",ulsch);
#endif
for (i=0; i<8; i++) {
if (ulsch->harq_processes[i]) {
if (ulsch->harq_processes[i]->b) {
free16(ulsch->harq_processes[i]->b,MAX_ULSCH_PAYLOAD_BYTES);
ulsch->harq_processes[i]->b = NULL;
}
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
if (ulsch->harq_processes[i]->c[r]) {
free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768);
ulsch->harq_processes[i]->c[r] = NULL;
}
}
free16(ulsch->harq_processes[i],sizeof(LTE_UL_UE_HARQ_t));
ulsch->harq_processes[i] = NULL;
}
}
free16(ulsch,sizeof(LTE_UE_ULSCH_t));
ulsch = NULL;
}
}
LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag)
{
LTE_UE_ULSCH_t *ulsch;
unsigned char exit_flag = 0,i,j,r;
unsigned char bw_scaling =1;
switch (N_RB_UL) {
case 6:
bw_scaling =16;
break;
case 25:
bw_scaling =4;
break;
case 50:
bw_scaling =2;
break;
default:
bw_scaling =1;
break;
}
ulsch = (LTE_UE_ULSCH_t *)malloc16(sizeof(LTE_UE_ULSCH_t));
if (ulsch) {
memset(ulsch,0,sizeof(LTE_UE_ULSCH_t));
ulsch->Mlimit = 4;
for (i=0; i<8; i++) {
ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t));
// printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]);
if (ulsch->harq_processes[i]) {
memset(ulsch->harq_processes[i], 0, sizeof(LTE_UL_UE_HARQ_t));
ulsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
if (ulsch->harq_processes[i]->b)
memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling);
else {
LOG_E(PHY,"Can't get b\n");
exit_flag=1;
}
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) {
ulsch->harq_processes[i]->c[r] = (unsigned char*)malloc16(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case
if (ulsch->harq_processes[i]->c[r])
memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768);
else {
LOG_E(PHY,"Can't get c\n");
exit_flag=2;
}
}
}
ulsch->harq_processes[i]->subframe_scheduling_flag = 0;
ulsch->harq_processes[i]->first_tx = 1;
} else {
LOG_E(PHY,"Can't get harq_p %d\n",i);
exit_flag=3;
}
}
if ((abstraction_flag == 0) && (exit_flag==0)) {
for (i=0; i<8; i++)
for (j=0; j<96; j++)
for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++)
ulsch->harq_processes[i]->d[r][j] = LTE_NULL;
return(ulsch);
} else if (abstraction_flag==1)
return(ulsch);
}
LOG_E(PHY,"new_ue_ulsch exit flag, size of %d , %zu\n",exit_flag, sizeof(LTE_UE_ULSCH_t));
free_ue_ulsch(ulsch);
return(NULL);
}
uint32_t ulsch_encoding(uint8_t *a,
PHY_VARS_UE *ue,
uint8_t harq_pid,
uint8_t eNB_id,
uint8_t subframe_rx,
uint8_t tmode,
uint8_t control_only_flag,
uint8_t Nbundled)
{
time_stats_t *seg_stats=&ue->ulsch_segmentation_stats;
time_stats_t *rm_stats=&ue->ulsch_rate_matching_stats;
time_stats_t *te_stats=&ue->ulsch_turbo_encoding_stats;
time_stats_t *i_stats=&ue->ulsch_interleaving_stats;
time_stats_t *m_stats=&ue->ulsch_multiplexing_stats;
// uint16_t offset;
uint32_t crc=1;
uint16_t iind;
uint32_t A;
uint8_t Q_m=0;
uint32_t Kr=0,Kr_bytes,r,r_offset=0;
uint8_t y[6*14*1200],*yptr;;
uint8_t *columnset;
uint32_t sumKr=0;
uint32_t Qprime,L,G,Q_CQI=0,Q_RI=0,Q_ACK=0,H=0,Hprime=0,Hpp=0,Cmux=0,Rmux=0,Rmux_prime=0;
uint32_t Qprime_ACK=0,Qprime_CQI=0,Qprime_RI=0,len_ACK=0,len_RI=0;
// uint32_t E;
uint8_t ack_parity;
uint32_t i,q,j,iprime,j2;
uint16_t o_RCC;
uint8_t o_flip[8];
uint32_t wACK_idx;
LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
PHY_MEASUREMENTS *meas = &ue->measurements;
LTE_UE_ULSCH_t *ulsch=ue->ulsch[eNB_id];
LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id];
uint16_t rnti = 0xffff;
if (!ulsch) {
LOG_E(PHY,"Null ulsch ptr %p\n",ulsch);
return(-1);
}
if (harq_pid >= 8) {
LOG_E(PHY,"Illegal harq_pid %d\n",harq_pid);
return(-1);
}
if (ulsch->harq_processes[harq_pid]->O_ACK > 2) {
LOG_E(PHY,"Illegal O_ACK %d\n",ulsch->harq_processes[harq_pid]->O_ACK);
return(-1);
}
if (ulsch->O_RI > 1) {
LOG_E(PHY,"Illegal O_RI %d\n",ulsch->O_RI);
return(-1);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
// fill CQI/PMI information
if (ulsch->O>0) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN);
rnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff);
LOG_D(PHY,"ULSCH Encoding rnti %x \n", rnti);
print_CQI(ulsch->o,ulsch->uci_format,0,ue->frame_parms.N_RB_DL);
// save PUSCH pmi for later (transmission modes 4,5,6)
if (dlsch[0]) {
//LOG_I(PHY,"XXX saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi));
dlsch[0]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_OUT);
}
if (ulsch->O<=32) {
o_flip[0] = ulsch->o[3];
o_flip[1] = ulsch->o[2];
o_flip[2] = ulsch->o[1];
o_flip[3] = ulsch->o[0];
} else {
o_flip[0] = ulsch->o[7];
o_flip[1] = ulsch->o[6];
o_flip[2] = ulsch->o[5];
o_flip[3] = ulsch->o[4];
o_flip[4] = ulsch->o[3];
o_flip[5] = ulsch->o[2];
o_flip[6] = ulsch->o[1];
o_flip[7] = ulsch->o[0];
}
if (control_only_flag == 0) {
A=ulsch->harq_processes[harq_pid]->TBS;
Q_m = get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs);
ulsch->harq_processes[harq_pid]->control_only = 0;
#ifdef DEBUG_ULSCH_CODING
printf("[PHY][UE] ULSCH coding : A %d, Qm %d, mcs %d, harq_pid %d, round %d, RV %d\n",
ulsch->harq_processes[harq_pid]->TBS,
Q_m,
ulsch->harq_processes[harq_pid]->mcs,
harq_pid,
ulsch->harq_processes[harq_pid]->round,
ulsch->harq_processes[harq_pid]->rvidx);
for (i=0; i<ulsch->harq_processes[harq_pid]->O_ACK; i++)
printf("ulsch_coding: o_ACK[%d] %d\n",i,ulsch->o_ACK[i]);
for (i=0; i<ulsch->O_RI; i++)
printf("ulsch_coding: o_RI[%d] %d\n",i,ulsch->o_RI[i]);
printf("ulsch_coding: O=%d\n",ulsch->O);
for (i=0; i<1+((8+ulsch->O)/8); i++) {
// ulsch->o[i] = i;
printf("ulsch_coding: O[%d] %d\n",i,ulsch->o[i]);
}
if ((tmode != 4))
print_CQI(ulsch->o,wideband_cqi_rank1_2A,0,ue->frame_parms.N_RB_DL);
else
print_CQI(ulsch->o,HLC_subband_cqi_rank1_2A,0,ue->frame_parms.N_RB_DL);
#endif
if (ulsch->harq_processes[harq_pid]->round == 0) { // this is a new packet
start_meas(seg_stats);
// Add 24-bit crc (polynomial A) to payload
crc = crc24a(a,
A)>>8;
a[A>>3] = ((uint8_t*)&crc)[2];
a[1+(A>>3)] = ((uint8_t*)&crc)[1];
a[2+(A>>3)] = ((uint8_t*)&crc)[0];
ulsch->harq_processes[harq_pid]->B = A+24;
ulsch->harq_processes[harq_pid]->b = a;
lte_segmentation(ulsch->harq_processes[harq_pid]->b,
ulsch->harq_processes[harq_pid]->c,
ulsch->harq_processes[harq_pid]->B,
&ulsch->harq_processes[harq_pid]->C,
&ulsch->harq_processes[harq_pid]->Cplus,
&ulsch->harq_processes[harq_pid]->Cminus,
&ulsch->harq_processes[harq_pid]->Kplus,
&ulsch->harq_processes[harq_pid]->Kminus,
&ulsch->harq_processes[harq_pid]->F);
stop_meas(seg_stats);
for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
if (r<ulsch->harq_processes[harq_pid]->Cminus)
Kr = ulsch->harq_processes[harq_pid]->Kminus;
else
Kr = ulsch->harq_processes[harq_pid]->Kplus;
Kr_bytes = Kr>>3;
// get interleaver index for Turbo code (lookup in Table 5.1.3-3 36-212, V8.6 2009-03, p. 13-14)
if (Kr_bytes<=64)
iind = (Kr_bytes-5);
else if (Kr_bytes <=128)
iind = 59 + ((Kr_bytes-64)>>1);
else if (Kr_bytes <= 256)
iind = 91 + ((Kr_bytes-128)>>2);
else if (Kr_bytes <= 768)
iind = 123 + ((Kr_bytes-256)>>3);
else {
LOG_E(PHY,"ulsch_coding: Illegal codeword size %d!!!\n",Kr_bytes);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
}
#ifdef DEBUG_ULSCH_CODING
printf("Generating Code Segment %d (%d bits)\n",r,Kr);
// generate codewords
printf("bits_per_codeword (Kr)= %d\n",Kr);
printf("N_RB = %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
printf("Ncp %d\n",frame_parms->Ncp);
printf("Qm %d\n",Q_m);
#endif
// offset=0;
#ifdef DEBUG_ULSCH_CODING
printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
#endif
start_meas(te_stats);
encoder(ulsch->harq_processes[harq_pid]->c[r],
Kr>>3,
&ulsch->harq_processes[harq_pid]->d[r][96],
(r==0) ? ulsch->harq_processes[harq_pid]->F : 0,
f1f2mat_old[iind*2], // f1 (see 36212-820, page 14)
f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14)
);
stop_meas(te_stats);
#ifdef DEBUG_ULSCH_CODING
if (r==0)
write_output("enc_output0.m","enc0",&ulsch->harq_processes[harq_pid]->d[r][96],(3*8*Kr_bytes)+12,1,4);
#endif
start_meas(i_stats);
ulsch->harq_processes[harq_pid]->RTC[r] =
sub_block_interleaving_turbo(4+(Kr_bytes*8),
&ulsch->harq_processes[harq_pid]->d[r][96],
ulsch->harq_processes[harq_pid]->w[r]);
stop_meas(i_stats);
}
}
if (ulsch->harq_processes[harq_pid]->C == 0) {
LOG_E(PHY,"null segment\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
}
sumKr = 0;
for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
if (r<ulsch->harq_processes[harq_pid]->Cminus)
Kr = ulsch->harq_processes[harq_pid]->Kminus;
else
Kr = ulsch->harq_processes[harq_pid]->Kplus;
sumKr += Kr;
}
} else { // This is a control-only PUSCH, set sumKr to O_CQI-MIN
ulsch->harq_processes[harq_pid]->control_only = 1;
sumKr = ulsch->O_CQI_MIN;
}
ulsch->harq_processes[harq_pid]->sumKr = sumKr;
// Compute Q_ri (p. 23 36-212)
Qprime = ulsch->O_RI*ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_ri_times8;
if (Qprime > 0) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
if (Qprime > 4*ulsch->harq_processes[harq_pid]->nb_rb * 12)
Qprime = 4*ulsch->harq_processes[harq_pid]->nb_rb * 12;
}
Q_RI = Q_m*Qprime;
Qprime_RI = Qprime;
// Compute Q_ack (p. 23 36-212)
Qprime = ulsch->harq_processes[harq_pid]->O_ACK*ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_harqack_times8;
if (Qprime > 0) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
if (Qprime > 4*ulsch->harq_processes[harq_pid]->nb_rb * 12)
Qprime = 4*ulsch->harq_processes[harq_pid]->nb_rb * 12;
}
Q_ACK = Qprime * Q_m;
Qprime_ACK = Qprime;
LOG_D(PHY,"UE (%x/%d) O_ACK %d, Mcs_initial %d, Nsymb_initial %d, beta_offset_harqack*8 %d, sum Kr %d, Qprime_ACK %d, Q_ACK %d\n",
rnti, harq_pid,
ulsch->harq_processes[harq_pid]->O_ACK,
ulsch->harq_processes[harq_pid]->Msc_initial,
ulsch->harq_processes[harq_pid]->Nsymb_initial,
ulsch->beta_offset_harqack_times8,
sumKr,
Qprime_ACK,
Q_ACK);
// Compute Q_cqi, assume O>11, p. 26 36-212
if (control_only_flag == 0) {
if (ulsch->O < 12)
L=0;
else
L=8;
if (ulsch->O > 0)
Qprime = (ulsch->O + L) * ulsch->harq_processes[harq_pid]->Msc_initial*ulsch->harq_processes[harq_pid]->Nsymb_initial * ulsch->beta_offset_cqi_times8;
else
Qprime = 0;
if (Qprime > 0) {
if ((Qprime % (8*sumKr)) > 0)
Qprime = 1+(Qprime/(8*sumKr));
else
Qprime = Qprime/(8*sumKr);
}
G = ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
if (Qprime > (G - ulsch->O_RI))
Qprime = G - ulsch->O_RI;
Q_CQI = Q_m * Qprime;
Qprime_CQI = Qprime;
G = G - Q_RI - Q_CQI;
ulsch->harq_processes[harq_pid]->G = G;
/*
LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d, Q_ACK %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI,Q_ACK);
LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n",
frame_parms->Nid_cell,ulsch->rnti,
harq_pid,
ulsch->harq_processes[harq_pid]->round,
ulsch->harq_processes[harq_pid]->rvidx,
ulsch->harq_processes[harq_pid]->mcs,
ulsch->O_RI,
ulsch->harq_processes[harq_pid]->O_ACK,
G);
*/
if ((int)G < 0) {
LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
}
// Data and control multiplexing (5.2.2.7 36-212)
H = G + Q_CQI;
Hprime = H/Q_m;
// Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the
// outputs for each code segment, see Section 5.1.5 p.20
for (r=0; r<ulsch->harq_processes[harq_pid]->C; r++) {
#ifdef DEBUG_ULSCH_CODING
printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n",
r,
G,
Kr*3,
Q_m,ulsch->harq_processes[harq_pid]->nb_rb);
#endif
start_meas(rm_stats);
r_offset += lte_rate_matching_turbo(ulsch->harq_processes[harq_pid]->RTC[r],
G,
ulsch->harq_processes[harq_pid]->w[r],
ulsch->e+r_offset,
ulsch->harq_processes[harq_pid]->C, // C
NSOFT, // Nsoft,
0, // this means UL
1,
ulsch->harq_processes[harq_pid]->rvidx,
get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs),
1,
r,
ulsch->harq_processes[harq_pid]->nb_rb);
//ulsch->harq_processes[harq_pid]->mcs); // r
stop_meas(rm_stats);
#ifdef DEBUG_ULSCH_CODING
if (r==ulsch->harq_processes[harq_pid]->C-1)
write_output("enc_output.m","enc",ulsch->e,r_offset,1,4);
#endif
}
} else { //control-only PUSCH
Q_CQI = (ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch)) - Q_RI;
H = Q_CQI;
Hprime = H/Q_m;
}
// Do CQI coding
if ((ulsch->O>1) && (ulsch->O < 12)) {
LOG_E(PHY,"short CQI sizes not supported yet\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
} else {
// add 8-bit CRC
crc = crc8(o_flip,
ulsch->O)>>24;
#ifdef DEBUG_ULSCH_CODING
printf("crc(cqi) tx : %x\n",crc);
#endif
memset((void *)&ulsch->o_d[0],LTE_NULL,96);
ccodelte_encode(ulsch->O,
1,
o_flip,
&ulsch->o_d[96],
0);
o_RCC = sub_block_interleaving_cc(8+ulsch->O,
&ulsch->o_d[96],
ulsch->o_w);
lte_rate_matching_cc(o_RCC,
Q_CQI,
ulsch->o_w,
ulsch->q);
}
i=0;
// Do RI coding
if (ulsch->O_RI == 1) {
switch (Q_m) {
case 2:
ulsch->q_RI[0] = ulsch->o_RI[0];
ulsch->q_RI[1] = PUSCH_y;//ulsch->o_RI[0];
len_RI=2;
break;
case 4:
ulsch->q_RI[0] = ulsch->o_RI[0];
ulsch->q_RI[1] = PUSCH_y;//1;
ulsch->q_RI[2] = PUSCH_x;//ulsch->o_RI[0];
ulsch->q_RI[3] = PUSCH_x;//1;
len_RI=4;
break;
case 6:
ulsch->q_RI[0] = ulsch->o_RI[0];
ulsch->q_RI[1] = PUSCH_y;//1;
ulsch->q_RI[2] = PUSCH_x;//1;
ulsch->q_RI[3] = PUSCH_x;//ulsch->o_RI[0];
ulsch->q_RI[4] = PUSCH_x;//1;
ulsch->q_RI[5] = PUSCH_x;//1;
len_RI=6;
break;
}
} else if (ulsch->O_RI>1) {
LOG_E(PHY,"RI cannot be more than 1 bit yet\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
}
// Do ACK coding, Section 5.2.2.6 36.213 (p.23-24 in v8.6)
wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3);
#ifdef DEBUG_ULSCH_CODING
printf("ulsch_coding.c: Bundling %d, Nbundled %d, wACK_idx %d\n",
ulsch->bundling,Nbundled,wACK_idx);
#endif
// 1-bit ACK/NAK
if (ulsch->harq_processes[harq_pid]->O_ACK == 1) {
switch (Q_m) {
case 2:
ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);//ulsch->o_ACK[0];
len_ACK = 2;
break;
case 4:
ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
ulsch->q_ACK[2] = PUSCH_x;
ulsch->q_ACK[3] = PUSCH_x;
len_ACK = 4;
break;
case 6:
ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[1] = (ulsch->bundling==0)? PUSCH_y : ((ulsch->o_ACK[0]+wACK[wACK_idx][1])&1);
ulsch->q_ACK[2] = PUSCH_x;
ulsch->q_ACK[3] = PUSCH_x;
ulsch->q_ACK[4] = PUSCH_x;
ulsch->q_ACK[6] = PUSCH_x;
len_ACK = 6;
break;
}
}
// two-bit ACK/NAK
if (ulsch->harq_processes[harq_pid]->O_ACK == 2) {
ack_parity = (ulsch->o_ACK[0]+ulsch->o_ACK[1])&1;
switch (Q_m) {
case 2:
ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[2] = (ack_parity+wACK[wACK_idx][0])&1;
ulsch->q_ACK[3] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
ulsch->q_ACK[4] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
ulsch->q_ACK[5] = (ack_parity+wACK[wACK_idx][1])&1;
len_ACK = 6;
break;
case 4:
ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[2] = PUSCH_x;
ulsch->q_ACK[3] = PUSCH_x;//1;
ulsch->q_ACK[4] = (ack_parity+wACK[wACK_idx][0])&1;
ulsch->q_ACK[5] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
ulsch->q_ACK[6] = PUSCH_x;
ulsch->q_ACK[7] = PUSCH_x;//1;
ulsch->q_ACK[8] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
ulsch->q_ACK[9] = (ack_parity+wACK[wACK_idx][1])&1;
ulsch->q_ACK[10] = PUSCH_x;
ulsch->q_ACK[11] = PUSCH_x;//1;
len_ACK = 12;
break;
case 6:
ulsch->q_ACK[0] = (ulsch->o_ACK[0]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[1] = (ulsch->o_ACK[1]+wACK[wACK_idx][0])&1;
ulsch->q_ACK[2] = PUSCH_x;
ulsch->q_ACK[3] = PUSCH_x;
ulsch->q_ACK[4] = PUSCH_x;
ulsch->q_ACK[5] = PUSCH_x;
ulsch->q_ACK[6] = (ack_parity+wACK[wACK_idx][0])&1;
ulsch->q_ACK[7] = (ulsch->o_ACK[0]+wACK[wACK_idx][1])&1;
ulsch->q_ACK[8] = PUSCH_x;
ulsch->q_ACK[9] = PUSCH_x;
ulsch->q_ACK[10] = PUSCH_x;
ulsch->q_ACK[11] = PUSCH_x;
ulsch->q_ACK[12] = (ulsch->o_ACK[1]+wACK[wACK_idx][1])&1;
ulsch->q_ACK[13] = (ack_parity+wACK[wACK_idx][1])&1;
ulsch->q_ACK[14] = PUSCH_x;
ulsch->q_ACK[15] = PUSCH_x;
ulsch->q_ACK[16] = PUSCH_x;
ulsch->q_ACK[17] = PUSCH_x;
len_ACK = 18;
break;
}
}
if (ulsch->harq_processes[harq_pid]->O_ACK > 2) {
LOG_E(PHY,"ACK cannot be more than 2 bits yet\n");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
}
// channel multiplexing/interleaving
start_meas(m_stats);
Hpp = Hprime + Q_RI;
Cmux = ulsch->Nsymb_pusch;
Rmux = Hpp*Q_m/Cmux;
Rmux_prime = Rmux/Q_m;
Qprime_RI = Q_RI / Q_m;
Qprime_ACK = Q_ACK / Q_m;
Qprime_CQI = Q_CQI / Q_m;
// printf("Qprime_CQI = %d\n",Qprime_CQI);
// RI BITS
memset(y,LTE_NULL,Q_m*Hpp);
if (frame_parms->Ncp == 0)
columnset = cs_ri_normal;
else
columnset = cs_ri_extended;
j=0;
for (i=0; i<Qprime_RI; i++) {
r = Rmux_prime - 1 - (i>>2);
for (q=0; q<Q_m; q++) {
y[q+(Q_m*((r*Cmux) + columnset[j]))] = ulsch->q_RI[(q+(Q_m*i))%len_RI];
// printf("ri[%d] %d => y[%d]\n",q+(Q_m*i)%len_RI,ulsch->q_RI[(q+(Q_m*i))%len_RI],q+(Q_m*((r*Cmux) + columnset[j])),y[q+(Q_m*((r*Cmux) + columnset[j]))]);
}
j=(j+3)&3;
}
// CQI and Data bits
j=0;
/*
for (i=0,iprime=-Qprime_CQI;i<Hprime;i++,iprime++) {
while (y[Q_m*j] != LTE_NULL) j++;
if (i<Qprime_CQI) {
for (q=0;q<Q_m;q++) {
y[q+(Q_m*j)] = ulsch->q[q+(Q_m*i)];
//printf("cqi[%d] %d => y[%d]\n",q+(Q_m*i),ulsch->q[q+(Q_m*i)],q+(Q_m*j));
}
}
else {
for (q=0;q<Q_m;q++) {
y[q+(Q_m*j)] = ulsch->e[q+(Q_m*iprime)];
// printf("e[%d] %d => y[%d]\n",q+(Q_m*iprime),ulsch->e[q+(Q_m*iprime)],q+(Q_m*j));
}
}
j++;
}
*/
for (i=0; i<Qprime_CQI; i++) {
while (y[Q_m*j] != LTE_NULL) j++;
for (q=0; q<Q_m; q++) {
y[q+(Q_m*j)] = ulsch->q[q+(Q_m*i)];
// printf("cqi[%d] %d => y[%d] (j %d)\n",q+(Q_m*i),ulsch->q[q+(Q_m*i)],q+(Q_m*j),j);
}
j++;
}
j2 = j*Q_m;
switch (Q_m) {
case 2:
for (iprime=0; iprime<(Hprime-Qprime_CQI)<<1; iprime+=2) {
while (y[j2] != LTE_NULL) j2+=2;
y[j2] = ulsch->e[iprime];
y[1+j2] = ulsch->e[1+iprime];
j2+=2;
}
break;
case 4:
for (iprime=0; iprime<(Hprime-Qprime_CQI)<<2; iprime+=4) {
while (y[j2] != LTE_NULL) j2+=4;
y[j2] = ulsch->e[iprime];
y[1+j2] = ulsch->e[1+iprime];
y[2+j2] = ulsch->e[2+iprime];
y[3+j2] = ulsch->e[3+iprime];
j2+=4;
}
break;
case 6:
for (iprime=0; iprime<(Hprime-Qprime_CQI)*6; iprime+=6) {
while (y[j2] != LTE_NULL) j2+=6;
y[j2] = ulsch->e[iprime];
y[1+j2] = ulsch->e[1+iprime];
y[2+j2] = ulsch->e[2+iprime];
y[3+j2] = ulsch->e[3+iprime];
y[4+j2] = ulsch->e[4+iprime];
y[5+j2] = ulsch->e[5+iprime];
j2+=6;
}
break;
}
// HARQ-ACK Bits (Note these overwrite some bits)
if (frame_parms->Ncp == 0)
columnset = cs_ack_normal;
else
columnset = cs_ack_extended;
j=0;
for (i=0; i<Qprime_ACK; i++) {
r = Rmux_prime - 1 - (i>>2);
for (q=0; q<Q_m; q++) {
y[q+(Q_m*((r*Cmux) + columnset[j]))] = ulsch->q_ACK[(q+(Q_m*i))%len_ACK];
#ifdef DEBUG_ULSCH_CODING
printf("ulsch_coding.c: ACK %d => y[%d]=%d (i %d, r*Cmux %d, columnset %d)\n",q+(Q_m*i),
q+(Q_m*((r*Cmux) + columnset[j])),ulsch->q_ACK[(q+(Q_m*i))%len_ACK],
i,r*Cmux,columnset[j]);
#endif
}
j=(j+3)&3;
}
// write out buffer
j=0;
switch (Q_m) {
case 2:
for (i=0; i<Cmux; i++)
for (r=0; r<Rmux_prime; r++) {
yptr=&y[((r*Cmux)+i)<<1];
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
}
break;
case 4:
for (i=0; i<Cmux; i++)
for (r=0; r<Rmux_prime; r++) {
yptr = &y[((r*Cmux)+i)<<2];
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
}
break;
case 6:
for (i=0; i<Cmux; i++)
for (r=0; r<Rmux_prime; r++) {
yptr = &y[((r*Cmux)+i)*6];
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
ulsch->h[j++] = *yptr++;
}
break;
default:
break;
}
stop_meas(m_stats);
if (j!=(H+Q_RI)) {
LOG_E(PHY,"Error in output buffer length (j %d, H+Q_RI %d)\n",j,H+Q_RI);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(-1);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
}
/*
* 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/LTE_TRANSPORT/ulsch_modulation.c
* \brief Top-level routines for generating PUSCH physical channel from 36.211 V8.6 2009-03
* \author R. Knopp, F. Kaltenberger, A. Bhamri
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,ankit.bhamri@eurecom.fr
* \note
* \warning
*/
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "PHY/CODING/defs.h"
#include "PHY/CODING/extern.h"
#include "PHY/LTE_TRANSPORT/defs.h"
#include "defs.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
//#define DEBUG_ULSCH_MODULATION
#ifndef OFDMA_ULSCH
void dft_lte(int32_t *z,int32_t *d, int32_t Msc_PUSCH, uint8_t Nsymb)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i dft_in128[4][1200],dft_out128[4][1200];
#elif defined(__arm__)
int16x8_t dft_in128[4][1200],dft_out128[4][1200];
#endif
uint32_t *dft_in0=(uint32_t*)dft_in128[0],*dft_out0=(uint32_t*)dft_out128[0];
uint32_t *dft_in1=(uint32_t*)dft_in128[1],*dft_out1=(uint32_t*)dft_out128[1];
uint32_t *dft_in2=(uint32_t*)dft_in128[2],*dft_out2=(uint32_t*)dft_out128[2];
// uint32_t *dft_in3=(uint32_t*)dft_in128[3],*dft_out3=(uint32_t*)dft_out128[3];
uint32_t *d0,*d1,*d2,*d3,*d4,*d5,*d6,*d7,*d8,*d9,*d10,*d11;
uint32_t *z0,*z1,*z2,*z3,*z4,*z5,*z6,*z7,*z8,*z9,*z10,*z11;
uint32_t i,ip;
#if defined(__x86_64__) || defined(__i386__)
__m128i norm128;
#elif defined(__arm__)
int16x8_t norm128;
#endif
// printf("Doing lte_dft for Msc_PUSCH %d\n",Msc_PUSCH);
d0 = (uint32_t *)d;
d1 = d0+Msc_PUSCH;
d2 = d1+Msc_PUSCH;
d3 = d2+Msc_PUSCH;
d4 = d3+Msc_PUSCH;
d5 = d4+Msc_PUSCH;
d6 = d5+Msc_PUSCH;
d7 = d6+Msc_PUSCH;
d8 = d7+Msc_PUSCH;
d9 = d8+Msc_PUSCH;
d10 = d9+Msc_PUSCH;
d11 = d10+Msc_PUSCH;
// printf("symbol 0 (d0 %p, d %p)\n",d0,d);
for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
dft_in0[ip] = d0[i];
dft_in0[ip+1] = d1[i];
dft_in0[ip+2] = d2[i];
dft_in0[ip+3] = d3[i];
dft_in1[ip] = d4[i];
dft_in1[ip+1] = d5[i];
dft_in1[ip+2] = d6[i];
dft_in1[ip+3] = d7[i];
dft_in2[ip] = d8[i];
dft_in2[ip+1] = d9[i];
dft_in2[ip+2] = d10[i];
dft_in2[ip+3] = d11[i];
// printf("dft%d %d: %d,%d,%d,%d\n",Msc_PUSCH,ip,d0[i],d1[i],d2[i],d3[i]);
// dft_in_re2[ip+1] = d9[i];
// dft_in_re2[ip+2] = d10[i];
}
// printf("\n");
switch (Msc_PUSCH) {
case 12:
dft12((int16_t *)dft_in0,(int16_t *)dft_out0);
dft12((int16_t *)dft_in1,(int16_t *)dft_out1);
dft12((int16_t *)dft_in2,(int16_t *)dft_out2);
/*
dft12f(&((__m128i *)dft_in0)[0],&((__m128i *)dft_in0)[1],&((__m128i *)dft_in0)[2],&((__m128i *)dft_in0)[3],&((__m128i *)dft_in0)[4],&((__m128i *)dft_in0)[5],&((__m128i *)dft_in0)[6],&((__m128i *)dft_in0)[7],&((__m128i *)dft_in0)[8],&((__m128i *)dft_in0)[9],&((__m128i *)dft_in0)[10],&((__m128i *)dft_in0)[11],
&((__m128i *)dft_out0)[0],&((__m128i *)dft_out0)[1],&((__m128i *)dft_out0)[2],&((__m128i *)dft_out0)[3],&((__m128i *)dft_out0)[4],&((__m128i *)dft_out0)[5],&((__m128i *)dft_out0)[6],&((__m128i *)dft_out0)[7],&((__m128i *)dft_out0)[8],&((__m128i *)dft_out0)[9],&((__m128i *)dft_out0)[10],&((__m128i *)dft_out0)[11]);
dft12f(&((__m128i *)dft_in1)[0],&((__m128i *)dft_in1)[1],&((__m128i *)dft_in1)[2],&((__m128i *)dft_in1)[3],&((__m128i *)dft_in1)[4],&((__m128i *)dft_in1)[5],&((__m128i *)dft_in1)[6],&((__m128i *)dft_in1)[7],&((__m128i *)dft_in1)[8],&((__m128i *)dft_in1)[9],&((__m128i *)dft_in1)[10],&((__m128i *)dft_in1)[11],
&((__m128i *)dft_out1)[0],&((__m128i *)dft_out1)[1],&((__m128i *)dft_out1)[2],&((__m128i *)dft_out1)[3],&((__m128i *)dft_out1)[4],&((__m128i *)dft_out1)[5],&((__m128i *)dft_out1)[6],&((__m128i *)dft_out1)[7],&((__m128i *)dft_out1)[8],&((__m128i *)dft_out1)[9],&((__m128i *)dft_out1)[10],&((__m128i *)dft_out1)[11]);
dft12f(&((__m128i *)dft_in2)[0],&((__m128i *)dft_in2)[1],&((__m128i *)dft_in2)[2],&((__m128i *)dft_in2)[3],&((__m128i *)dft_in2)[4],&((__m128i *)dft_in2)[5],&((__m128i *)dft_in2)[6],&((__m128i *)dft_in2)[7],&((__m128i *)dft_in2)[8],&((__m128i *)dft_in2)[9],&((__m128i *)dft_in2)[10],&((__m128i *)dft_in2)[11],
&((__m128i *)dft_out2)[0],&((__m128i *)dft_out2)[1],&((__m128i *)dft_out2)[2],&((__m128i *)dft_out2)[3],&((__m128i *)dft_out2)[4],&((__m128i *)dft_out2)[5],&((__m128i *)dft_out2)[6],&((__m128i *)dft_out2)[7],&((__m128i *)dft_out2)[8],&((__m128i *)dft_out2)[9],&((__m128i *)dft_out2)[10],&((__m128i *)dft_out2)[11]);
*/
#if defined(__x86_64__) || defined(__i386__)
norm128 = _mm_set1_epi16(9459);
#elif defined(__arm__)
norm128 = vdupq_n_s16(9459);
#endif
for (i=0; i<12; i++) {
#if defined(__x86_64__) || defined(__i386__)
((__m128i*)dft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out0)[i],norm128),1);
((__m128i*)dft_out1)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out1)[i],norm128),1);
((__m128i*)dft_out2)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out2)[i],norm128),1);
#elif defined(__arm__)
((int16x8_t*)dft_out0)[i] = vqdmulhq_s16(((int16x8_t*)dft_out0)[i],norm128);
((int16x8_t*)dft_out1)[i] = vqdmulhq_s16(((int16x8_t*)dft_out1)[i],norm128);
((int16x8_t*)dft_out2)[i] = vqdmulhq_s16(((int16x8_t*)dft_out2)[i],norm128);
#endif
}
break;
case 24:
dft24((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft24((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft24((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 36:
dft36((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft36((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft36((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 48:
dft48((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft48((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft48((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 60:
dft60((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft60((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft60((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 72:
dft72((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft72((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft72((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 96:
dft96((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft96((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft96((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 108:
dft108((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft108((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft108((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 120:
dft120((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft120((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft120((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 144:
dft144((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft144((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft144((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 180:
dft180((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft180((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft180((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 192:
dft192((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft192((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft192((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 216:
dft216((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft216((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft216((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 240:
dft240((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft240((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft240((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 288:
dft288((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft288((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft288((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 300:
dft300((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft300((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft300((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 324:
dft324((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft324((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft324((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 360:
dft360((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft360((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft360((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 384:
dft384((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft384((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft384((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 432:
dft432((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft432((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft432((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 480:
dft480((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft480((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft480((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 540:
dft540((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft540((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft540((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 576:
dft576((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft576((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft576((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 600:
dft600((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft600((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft600((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 648:
dft648((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft648((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft648((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 720:
dft720((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft720((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft720((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 864:
dft864((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft864((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft864((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 900:
dft900((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft900((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft900((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 960:
dft960((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft960((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft960((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 972:
dft972((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft972((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft972((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 1080:
dft1080((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft1080((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft1080((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 1152:
dft1152((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft1152((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft1152((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
case 1200:
dft1200((int16_t*)dft_in0,(int16_t*)dft_out0,1);
dft1200((int16_t*)dft_in1,(int16_t*)dft_out1,1);
dft1200((int16_t*)dft_in2,(int16_t*)dft_out2,1);
break;
}
z0 = (uint32_t *)z;
z1 = z0+Msc_PUSCH;
z2 = z1+Msc_PUSCH;
z3 = z2+Msc_PUSCH;
z4 = z3+Msc_PUSCH;
z5 = z4+Msc_PUSCH;
z6 = z5+Msc_PUSCH;
z7 = z6+Msc_PUSCH;
z8 = z7+Msc_PUSCH;
z9 = z8+Msc_PUSCH;
z10 = z9+Msc_PUSCH;
z11 = z10+Msc_PUSCH;
// printf("symbol0 (dft)\n");
for (i=0,ip=0; i<Msc_PUSCH; i++,ip+=4) {
z0[i] = dft_out0[ip];
// printf("%d,%d,",((short*)&z0[i])[0],((short*)&z0[i])[1]);
z1[i] = dft_out0[ip+1];
z2[i] = dft_out0[ip+2];
z3[i] = dft_out0[ip+3];
z4[i] = dft_out1[ip+0];
z5[i] = dft_out1[ip+1];
z6[i] = dft_out1[ip+2];
z7[i] = dft_out1[ip+3];
z8[i] = dft_out2[ip];
z9[i] = dft_out2[ip+1];
z10[i] = dft_out2[ip+2];
z11[i] = dft_out2[ip+3];
// printf("out dft%d %d: %d,%d,%d,%d,%d,%d,%d,%d\n",Msc_PUSCH,ip,z0[i],z1[i],z2[i],z3[i],z4[i],z5[i],z6[i],z7[i]);
}
// printf("\n");
}
#endif
void ulsch_modulation(int32_t **txdataF,
short amp,
uint32_t frame,
uint32_t subframe,
LTE_DL_FRAME_PARMS *frame_parms,
LTE_UE_ULSCH_t *ulsch)
{
uint8_t qam64_table_offset_re = 0;
uint8_t qam64_table_offset_im = 0;
uint8_t qam16_table_offset_re = 0;
uint8_t qam16_table_offset_im = 0;
short gain_lin_QPSK;
DevAssert(frame_parms);
int re_offset,re_offset0,i,Msymb,j,k,nsymb,Msc_PUSCH,l;
// uint8_t harq_pid = (rag_flag == 1) ? 0 : subframe2harq_pid_tdd(frame_parms->tdd_config,subframe);
uint8_t harq_pid = subframe2harq_pid(frame_parms,frame,subframe);
uint8_t Q_m;
int32_t *txptr;
uint32_t symbol_offset;
uint16_t first_rb;
uint16_t nb_rb;
int G;
uint32_t x1, x2, s=0;
uint8_t c;
if (!ulsch) {
printf("ulsch_modulation.c: Null ulsch\n");
return;
}
// x1 is set in lte_gold_generic
x2 = (ulsch->rnti<<14) + (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1
if (harq_pid>=8) {
printf("ulsch_modulation.c: Illegal harq_pid %d\n",harq_pid);
return;
}
first_rb = ulsch->harq_processes[harq_pid]->first_rb;
nb_rb = ulsch->harq_processes[harq_pid]->nb_rb;
if (nb_rb == 0) {
printf("ulsch_modulation.c: Frame %d, Subframe %d Illegal nb_rb %d\n",frame,subframe,nb_rb);
return;
}
if (first_rb > frame_parms->N_RB_UL) {
printf("ulsch_modulation.c: Frame %d, Subframe %d Illegal first_rb %d\n",frame,subframe,first_rb);
return;
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_FUNCTION_IN);
Q_m = get_Qm_ul(ulsch->harq_processes[harq_pid]->mcs);
G = (int)ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
// Mapping
nsymb = (frame_parms->Ncp==0) ? 14:12;
Msc_PUSCH = ulsch->harq_processes[harq_pid]->nb_rb*12;
#ifdef DEBUG_ULSCH_MODULATION
LOG_D(PHY,"ulsch_modulation.c: Doing modulation (rnti %x,x2 %x) for G=%d bits, harq_pid %d , nb_rb %d, Q_m %d, Nsymb_pusch %d (nsymb %d), subframe %d\n",
ulsch->rnti,x2,G,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,Q_m, ulsch->Nsymb_pusch,nsymb,subframe);
#endif
// scrambling (Note the placeholding bits are handled in ulsch_coding.c directly!)
//printf("ulsch bits: ");
s = lte_gold_generic(&x1, &x2, 1);
k=0;
//printf("G %d\n",G);
for (i=0; i<(1+(G>>5)); i++) {
for (j=0; j<32; j++,k++) {
c = (uint8_t)((s>>j)&1);
if (ulsch->h[k] == PUSCH_x) {
// printf("i %d: PUSCH_x\n",i);
ulsch->b_tilde[k] = 1;
} else if (ulsch->h[k] == PUSCH_y) {
// printf("i %d: PUSCH_y\n",i);
ulsch->b_tilde[k] = ulsch->b_tilde[k-1];
} else {
ulsch->b_tilde[k] = (ulsch->h[k]+c)&1;
// printf("i %d : %d (h %d c %d)\n", (i<<5)+j,ulsch->b_tilde[k],ulsch->h[k],c);
}
}
s = lte_gold_generic(&x1, &x2, 0);
}
//printf("\n");
gain_lin_QPSK = (short)((amp*ONE_OVER_SQRT2_Q15)>>15);
// Modulation
Msymb = G/Q_m;
if(ulsch->cooperation_flag == 2)
// For Distributed Alamouti Scheme in Collabrative Communication
{
for (i=0,j=Q_m; i<Msymb; i+=2,j+=2*Q_m) {
switch (Q_m) {
case 2:
//UE1, -x1*
((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
// if (i<Msc_PUSCH)
// printf("input %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
// UE1, x0*
((int16_t*)&ulsch->d[i+1])[0] = (ulsch->b_tilde[j-2] == 1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
((int16_t*)&ulsch->d[i+1])[1] = (ulsch->b_tilde[j-1] == 1)? (gain_lin_QPSK) : -gain_lin_QPSK;
break;
case 4:
//UE1,-x1*
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (ulsch->b_tilde[j] == 1)
qam16_table_offset_re+=2;
if (ulsch->b_tilde[j+1] == 1)
qam16_table_offset_im+=2;
if (ulsch->b_tilde[j+2] == 1)
qam16_table_offset_re+=1;
if (ulsch->b_tilde[j+3] == 1)
qam16_table_offset_im+=1;
((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
//UE1,x0*
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (ulsch->b_tilde[j-4] == 1)
qam16_table_offset_re+=2;
if (ulsch->b_tilde[j-3] == 1)
qam16_table_offset_im+=2;
if (ulsch->b_tilde[j-2] == 1)
qam16_table_offset_re+=1;
if (ulsch->b_tilde[j-1] == 1)
qam16_table_offset_im+=1;
// ((int16_t*)&ulsch->d[i+1])[0]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
// ((int16_t*)&ulsch->d[i+1])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
break;
case 6:
//UE1,-x1*FPGA_UE
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
if (ulsch->b_tilde[j] == 1)
qam64_table_offset_re+=4;
if (ulsch->b_tilde[j+1] == 1)
qam64_table_offset_im+=4;
if (ulsch->b_tilde[j+2] == 1)
qam64_table_offset_re+=2;
if (ulsch->b_tilde[j+3] == 1)
qam64_table_offset_im+=2;
if (ulsch->b_tilde[j+4] == 1)
qam64_table_offset_re+=1;
if (ulsch->b_tilde[j+5] == 1)
qam64_table_offset_im+=1;
((int16_t*)&ulsch->d[i])[0]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
//UE1,x0*
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
if (ulsch->b_tilde[j-6] == 1)
qam64_table_offset_re+=4;
if (ulsch->b_tilde[j-5] == 1)
qam64_table_offset_im+=4;
if (ulsch->b_tilde[j-4] == 1)
qam64_table_offset_re+=2;
if (ulsch->b_tilde[j-3] == 1)
qam64_table_offset_im+=2;
if (ulsch->b_tilde[j-2] == 1)
qam64_table_offset_re+=1;
if (ulsch->b_tilde[j-1] == 1)
qam64_table_offset_im+=1;
((int16_t*)&ulsch->d[i+1])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
((int16_t*)&ulsch->d[i+1])[1]=-(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
break;
}//switch
}//for
}//cooperation_flag == 2
else {
for (i=0,j=0; i<Msymb; i++,j+=Q_m) {
switch (Q_m) {
case 2:
// TODO: this has to be updated!!!
((int16_t*)&ulsch->d[i])[0] = (ulsch->b_tilde[j] == 1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
((int16_t*)&ulsch->d[i])[1] = (ulsch->b_tilde[j+1] == 1)? (-gain_lin_QPSK) : gain_lin_QPSK;
// if (i<Msc_PUSCH)
// printf("input %d/%d Msc_PUSCH %d (%p): %d,%d\n", i,Msymb,Msc_PUSCH,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
break;
case 4:
qam16_table_offset_re = 0;
qam16_table_offset_im = 0;
if (ulsch->b_tilde[j] == 1)
qam16_table_offset_re+=2;
if (ulsch->b_tilde[j+1] == 1)
qam16_table_offset_im+=2;
if (ulsch->b_tilde[j+2] == 1)
qam16_table_offset_re+=1;
if (ulsch->b_tilde[j+3] == 1)
qam16_table_offset_im+=1;
((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
// printf("input(16qam) %d (%p): %d,%d\n", i,&ulsch->d[i],((int16_t*)&ulsch->d[i])[0],((int16_t*)&ulsch->d[i])[1]);
break;
case 6:
qam64_table_offset_re = 0;
qam64_table_offset_im = 0;
if (ulsch->b_tilde[j] == 1)
qam64_table_offset_re+=4;
if (ulsch->b_tilde[j+1] == 1)
qam64_table_offset_im+=4;
if (ulsch->b_tilde[j+2] == 1)
qam64_table_offset_re+=2;
if (ulsch->b_tilde[j+3] == 1)
qam64_table_offset_im+=2;
if (ulsch->b_tilde[j+4] == 1)
qam64_table_offset_re+=1;
if (ulsch->b_tilde[j+5] == 1)
qam64_table_offset_im+=1;
((int16_t*)&ulsch->d[i])[0]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
((int16_t*)&ulsch->d[i])[1]=(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
break;
}
}
}// normal symbols
// Transform Precoding
#ifdef OFDMA_ULSCH
for (i=0; i<Msymb; i++) {
ulsch->z[i] = ulsch->d[i];
}
#else
dft_lte(ulsch->z,ulsch->d,Msc_PUSCH,ulsch->Nsymb_pusch);
#endif
DevAssert(txdataF);
#ifdef OFDMA_ULSCH
re_offset0 = frame_parms->first_carrier_offset + (ulsch->harq_processes[harq_pid]->first_rb*12);
if (re_offset0>frame_parms->ofdm_symbol_size) {
re_offset0 -= frame_parms->ofdm_symbol_size;
// re_offset0++;
}
// printf("re_offset0 %d\n",re_offset0);
for (j=0,l=0; l<(nsymb-ulsch->srs_active); l++) {
re_offset = re_offset0;
symbol_offset = (int)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
#ifdef DEBUG_ULSCH_MODULATION
printf("symbol %d (subframe %d): symbol_offset %d\n",l,subframe,symbol_offset);
#endif
txptr = &txdataF[0][symbol_offset];
if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||
((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
}
// Skip reference symbols
else {
// printf("copying %d REs\n",Msc_PUSCH);
for (i=0; i<Msc_PUSCH; i++,j++) {
#ifdef DEBUG_ULSCH_MODULATION
printf("re_offset %d (%p): %d,%d\n", re_offset,&ulsch->z[j],((int16_t*)&ulsch->z[j])[0],((int16_t*)&ulsch->z[j])[1]);
#endif
txptr[re_offset++] = ulsch->z[j];
if (re_offset==frame_parms->ofdm_symbol_size)
re_offset = 0;
}
}
}
# else // OFDMA_ULSCH = 0
re_offset0 = frame_parms->first_carrier_offset + (ulsch->harq_processes[harq_pid]->first_rb*12);
if (re_offset0>frame_parms->ofdm_symbol_size) {
re_offset0 -= frame_parms->ofdm_symbol_size;
// re_offset0++;
}
// printf("re_offset0 %d\n",re_offset0);
// printf("txdataF %p\n",&txdataF[0][0]);
for (j=0,l=0; l<(nsymb-ulsch->srs_active); l++) {
re_offset = re_offset0;
symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(l+(subframe*nsymb));
#ifdef DEBUG_ULSCH_MODULATION
printf("ulsch_mod (SC-FDMA) symbol %d (subframe %d): symbol_offset %d\n",l,subframe,symbol_offset);
#endif
txptr = &txdataF[0][symbol_offset];
if (((frame_parms->Ncp == 0) && ((l==3) || (l==10)))||
((frame_parms->Ncp == 1) && ((l==2) || (l==8)))) {
}
// Skip reference symbols
else {
// printf("copying %d REs\n",Msc_PUSCH);
for (i=0; i<Msc_PUSCH; i++,j++) {
#ifdef DEBUG_ULSCH_MODULATION
printf("re_offset %d (%p): %d,%d => %p\n", re_offset,&ulsch->z[j],((int16_t*)&ulsch->z[j])[0],((int16_t*)&ulsch->z[j])[1],&txptr[re_offset]);
#endif //DEBUG_ULSCH_MODULATION
txptr[re_offset++] = ulsch->z[j];
if (re_offset==frame_parms->ofdm_symbol_size)
re_offset = 0;
}
}
}
#endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION, VCD_FUNCTION_OUT);
}
......@@ -215,7 +215,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");
......
......@@ -35,7 +35,6 @@
#define MAX_BANDS_PER_RRU 4
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
#ifdef OCP_FRAMEWORK
......
......@@ -38,6 +38,7 @@
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
typedef struct {
uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3];
......
......@@ -1980,9 +1980,17 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}
if (strcmp(RateMatchPattern_mode , "dynamic") == 0){
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPattern_mode[j] = NR_RateMatchPattern__dummy_dynamic;
#else
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPattern_mode[j] = NR_RateMatchPattern__mode_dynamic;
#endif
}else if (strcmp(RateMatchPattern_mode , "semiStatic") == 0){
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPattern_mode[j] = NR_RateMatchPattern__dummy_semiStatic;
#else
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPattern_mode[j] = NR_RateMatchPattern__mode_semiStatic;
#endif
}else {
AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%s\" for RateMatchPattern_mode !\n",
RC.config_file_name, i, RateMatchPattern_mode);
......@@ -2440,41 +2448,86 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
switch(Common_dci_Format2_3_monitoringPeriodicity){
case 1:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl1;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n1;
#endif
break;
case 2:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl2;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n2;
#endif
break;
case 4:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl4;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n4;
#endif
break;
case 5:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl5;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n5;
#endif
break;
case 8:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl8;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n8;
#endif
break;
case 10:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl10;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n10;
#endif
break;
case 16:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl16;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n16;
#endif
break;
case 20:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy1_sl20;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_monitoringPeriodicity[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__monitoringPeriodicity_n20;
#endif
break;
default:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%d\" for Common_dci_Format2_3_dummy1 choice: 1,2,4,5,8,10,16,20 !\n",
RC.config_file_name, i, Common_dci_Format2_3_monitoringPeriodicity);
#else
AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%d\" for Common_dci_Format2_3_monitoringPeriodicity choice: 1,2,4,5,8,10,16,20 !\n",
RC.config_file_name, i, Common_dci_Format2_3_monitoringPeriodicity);
#endif
break;
}
switch(Common_dci_Format2_3_nrofPDCCH_Candidates){
case 1:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_nrofPDCCH_Candidates[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy2_n1;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_nrofPDCCH_Candidates[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__nrofPDCCH_Candidates_n1;
#endif
break;
case 2:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_nrofPDCCH_Candidates[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__dummy2_n2;
#else
NRRRC_CONFIGURATION_REQ (msg_p).Common_dci_Format2_3_nrofPDCCH_Candidates[j] = NR_SearchSpace__searchSpaceType__common__dci_Format2_3__nrofPDCCH_Candidates_n2;
#endif
break;
default:
AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%d\" for Common_dci_Format2_3_nrofPDCCH_Candidates choice: 1,2 !\n",
......@@ -2598,9 +2651,17 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}
if (strcmp(RateMatchPatternLTE_CRS_subframeAllocation_choice , "oneFrame") == 0){
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPatternLTE_CRS_subframeAllocation_choice[j] = NR_EUTRA_MBSFN_SubframeConfig__subframeAllocation1_PR_oneFrame;
#else
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPatternLTE_CRS_subframeAllocation_choice[j] = NR_EUTRA_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame;
#endif
}else if (strcmp(RateMatchPatternLTE_CRS_subframeAllocation_choice , "fourFrames") == 0){
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPatternLTE_CRS_subframeAllocation_choice[j] = NR_EUTRA_MBSFN_SubframeConfig__subframeAllocation1_PR_fourFrames;
#else
NRRRC_CONFIGURATION_REQ (msg_p).RateMatchPatternLTE_CRS_subframeAllocation_choice[j] = NR_EUTRA_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames;
#endif
}else {
AssertFatal (0,"Failed to parse gNB configuration file %s, gnb %d unknown value \"%s\" for RateMatchPatternLTE_CRS_subframeAllocation_choice !\n",
RC.config_file_name, i, RateMatchPatternLTE_CRS_subframeAllocation_choice);
......
......@@ -77,11 +77,6 @@
#include "targets/ARCH/COMMON/common_lib.h"
//solve implicit declaration
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
/** @defgroup _mac MAC
* @ingroup _oai2
* @{
......
......@@ -114,8 +114,13 @@ int8_t nr_ue_decode_mib(
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
frequency_range_t frequency_range = FR1;
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero);
uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1.searchSpaceZero);
#else
uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1 >> 4) & 0xf;
uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1 & 0xf);
#endif
int32_t num_rbs = -1;
int32_t num_symbols = -1;
int32_t rb_offset = -1;
......@@ -428,7 +433,11 @@ int8_t nr_ue_decode_mib(
mac->phy_config.config_req.pbch_config.subcarrier_spacing_common = mac->mib->subCarrierSpacingCommon;
mac->phy_config.config_req.pbch_config.ssb_subcarrier_offset = ssb_subcarrier_offset; // after calculation
mac->phy_config.config_req.pbch_config.dmrs_type_a_position = mac->mib->dmrs_TypeA_Position;
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
mac->phy_config.config_req.pbch_config.pdcch_config_sib1 = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero) * 16 + (mac->mib->pdcch_ConfigSIB1.searchSpaceZero);
#else
mac->phy_config.config_req.pbch_config.pdcch_config_sib1 = mac->mib->pdcch_ConfigSIB1;
#endif
mac->phy_config.config_req.pbch_config.cell_barred = mac->mib->cellBarred;
mac->phy_config.config_req.pbch_config.intra_frequency_reselection = mac->mib->intraFreqReselection;
mac->phy_config.config_req.pbch_config.half_frame_bit = half_frame_bit;
......
......@@ -232,7 +232,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
mib->message.choice.mib->subCarrierSpacingCommon,
mib->message.choice.mib->ssb_SubcarrierOffset,
mib->message.choice.mib->dmrs_TypeA_Position,
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero * 16 + mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero,
#else
mib->message.choice.mib->pdcch_ConfigSIB1,
#endif
mib->message.choice.mib->cellBarred,
mib->message.choice.mib->intraFreqReselection
);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3869,7 +3869,11 @@ uint64_t arfcn_to_freq(long arfcn) {
// Dump contents
if ((*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_systemInformation_r8 ||
#if (RRC_VERSION >= MAKE_VERSION(15, 3, 0))
(*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r15) {
#else
(*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_criticalExtensionsFuture) {
#endif
LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n",
(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count );
} else {
......
......@@ -234,15 +234,19 @@ uint8_t do_MIB_NR(rrc_gNB_carrier_data_t *carrier,
mib->message.choice.mib->systemFrameNumber.bits_unused=2;
//38.331 spare BIT STRING (SIZE (1))
uint16_t *spare= calloc(1, sizeof(uint16_t));
uint16_t *spare= CALLOC(1, sizeof(uint16_t));
if (spare == NULL) abort();
mib->message.choice.mib->spare.buf = (uint8_t *)spare;
mib->message.choice.mib->spare.size = 1;
mib->message.choice.mib->spare.bits_unused = 7; // This makes a spare of 1 bits
mib->message.choice.mib->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = (pdcch_ConfigSIB1 / 16);
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = (pdcch_ConfigSIB1 % 16);
#else
mib->message.choice.mib->pdcch_ConfigSIB1 = pdcch_ConfigSIB1;
#endif
switch (subCarrierSpacingCommon) {
case 15:
mib->message.choice.mib->subCarrierSpacingCommon = NR_MIB__subCarrierSpacingCommon_scs15or60;
......@@ -353,7 +357,11 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id,
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = CALLOC(1,sizeof(long));
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero = CALLOC(1,sizeof(long));
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = CALLOC(1,sizeof(struct NR_ControlResourceSet));
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList));
#else
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpace = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpace));
#endif
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = CALLOC(1,sizeof(NR_SearchSpaceId_t));
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation = CALLOC(1,sizeof(NR_SearchSpaceId_t));
(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->pagingSearchSpace = CALLOC(1,sizeof(NR_SearchSpaceId_t));
......@@ -377,8 +385,11 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id,
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = CALLOC(1,sizeof(NR_RSRP_Range_t));
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t));
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t));
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long));
#else
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoding = CALLOC(1,sizeof(long));
#endif
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t));
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon));
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = CALLOC(1,sizeof(long));
......@@ -574,20 +585,32 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id,
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel8 = CALLOC(1,sizeof(long));
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel16 = CALLOC(1,sizeof(long));
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3 = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType__common__dci_Format2_3));
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->dummy1 = CALLOC(1,sizeof(long));
#else
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->monitoringPeriodicity = CALLOC(1,sizeof(long));
#endif
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel1) = configuration->Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1[CC_id];
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel2) = configuration->Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2[CC_id];
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel4) = configuration->Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4[CC_id];
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel8) = configuration->Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8[CC_id];
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel16) = configuration->Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16[CC_id];
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->dummy1) = configuration->Common_dci_Format2_3_monitoringPeriodicity[CC_id];
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->dummy2 = configuration->Common_dci_Format2_3_nrofPDCCH_Candidates[CC_id];
#else
*(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->monitoringPeriodicity) = configuration->Common_dci_Format2_3_monitoringPeriodicity[CC_id];
bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->nrofPDCCH_Candidates = configuration->Common_dci_Format2_3_nrofPDCCH_Candidates[CC_id];
#endif
}else if (bwp_dl_searchspace->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific){
bwp_dl_searchspace->searchSpaceType->choice.ue_Specific->dci_Formats = configuration->ue_Specific__dci_Formats[CC_id];
}
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
ASN_SEQUENCE_ADD(&(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,&bwp_dl_searchspace);
#else
ASN_SEQUENCE_ADD(&(*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpace->list,&bwp_dl_searchspace);
#endif
*((*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1) = configuration->searchSpaceSIB1[CC_id];
*((*servingcellconfigcommon)->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation) = configuration->searchSpaceOtherSystemInformation[CC_id];
......@@ -675,7 +698,11 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id,
(*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig = configuration->restrictedSetConfig[CC_id];
if(configuration->msg3_transformPrecoding[CC_id]){
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
*((*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder) = NR_RACH_ConfigCommon__msg3_transformPrecoder_enabled;
#else
*((*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoding) = NR_RACH_ConfigCommon__msg3_transformPrecoding_enabled;
#endif
}
//Fill initialUplinkBWP -> BWP-UplinkCommon -> rach_ConfigCommon -> rach_ConfigGeneric//
......@@ -710,8 +737,11 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id,
*((*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal) = configuration->p0_nominal[CC_id];
*((*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon) = configuration->pucch_ResourceCommon[CC_id];
*((*servingcellconfigcommon)->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId) = configuration->hoppingId[CC_id];
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
(*servingcellconfigcommon)->uplinkConfigCommon->dummy = configuration->UL_timeAlignmentTimerCommon[CC_id];
#else
(*servingcellconfigcommon)->uplinkConfigCommon->timeAlignmentTimerCommon = configuration->UL_timeAlignmentTimerCommon[CC_id];
#endif
(*servingcellconfigcommon)->n_TimingAdvanceOffset = CALLOC(1,sizeof(long));
*((*servingcellconfigcommon)->n_TimingAdvanceOffset)=configuration->ServingCellConfigCommon_n_TimingAdvanceOffset[CC_id];
......@@ -820,7 +850,11 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id,
}
*(ratematchpattern->subcarrierSpacing) = configuration->RateMatchPattern_subcarrierSpacing[CC_id];
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
ratematchpattern->dummy = configuration->RateMatchPattern_mode[CC_id];
#else
ratematchpattern->mode = configuration->RateMatchPattern_mode[CC_id];
#endif
ASN_SEQUENCE_ADD(&(*servingcellconfigcommon)->rateMatchPatternToAddModList->list,&ratematchpattern);
......@@ -1049,7 +1083,11 @@ void do_MAC_CELLGROUP(uint8_t Mod_id,
mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = mac_cellgroup_config->phr_ProhibitTimer[CC_id];
mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = mac_cellgroup_config->phr_Tx_PowerFactorChange[CC_id];
mac_CellGroupConfig->phr_Config->choice.setup->multiplePHR = mac_cellgroup_config->multiplePHR[CC_id];
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
mac_CellGroupConfig->phr_Config->choice.setup->dummy = mac_cellgroup_config->phr_Type2SpCell[CC_id];
#else
mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2SpCell = mac_cellgroup_config->phr_Type2SpCell[CC_id];
#endif
mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2OtherCell = mac_cellgroup_config->phr_Type2OtherCell[CC_id];
mac_CellGroupConfig->phr_Config->choice.setup->phr_ModeOtherCG = mac_cellgroup_config->phr_ModeOtherCG[CC_id];
......@@ -1064,7 +1102,11 @@ void do_PHYSICALCELLGROUP(uint8_t Mod_id,
physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH = CALLOC(1,sizeof(long));
physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH = CALLOC(1,sizeof(long));
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
physicalCellGroupConfig->p_NR_FR1 = CALLOC(1,sizeof(NR_P_Max_t));
#else
physicalCellGroupConfig->p_NR = CALLOC(1,sizeof(NR_P_Max_t));
#endif
physicalCellGroupConfig->tpc_SRS_RNTI = CALLOC(1,sizeof(NR_RNTI_Value_t));
physicalCellGroupConfig->tpc_PUCCH_RNTI = CALLOC(1,sizeof(NR_RNTI_Value_t));
physicalCellGroupConfig->tpc_PUSCH_RNTI = CALLOC(1,sizeof(NR_RNTI_Value_t));
......@@ -1072,7 +1114,11 @@ void do_PHYSICALCELLGROUP(uint8_t Mod_id,
*(physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH) = physicalcellgroup_config->harq_ACK_SpatialBundlingPUCCH[CC_id];
*(physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH) = physicalcellgroup_config->harq_ACK_SpatialBundlingPUSCH[CC_id];
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
*(physicalCellGroupConfig->p_NR_FR1) = physicalcellgroup_config->p_NR[CC_id];
#else
*(physicalCellGroupConfig->p_NR) = physicalcellgroup_config->p_NR[CC_id];
#endif
physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook = physicalcellgroup_config->pdsch_HARQ_ACK_Codebook[CC_id];
*(physicalCellGroupConfig->tpc_SRS_RNTI) = physicalcellgroup_config->tpc_SRS_RNTI[CC_id];
*(physicalCellGroupConfig->tpc_PUCCH_RNTI) = physicalcellgroup_config->tpc_PUCCH_RNTI[CC_id];
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -385,6 +385,16 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
break;
case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
#if (NR_RRC_VERSION >= MAKE_VERSION(15, 3, 0))
case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
#else
case NR_DL_DCCH_MessageType__c1_PR_spare15:
case NR_DL_DCCH_MessageType__c1_PR_spare14:
case NR_DL_DCCH_MessageType__c1_PR_spare13:
......@@ -393,6 +403,7 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
case NR_DL_DCCH_MessageType__c1_PR_spare10:
case NR_DL_DCCH_MessageType__c1_PR_spare9:
case NR_DL_DCCH_MessageType__c1_PR_spare8:
#endif
case NR_DL_DCCH_MessageType__c1_PR_spare7:
case NR_DL_DCCH_MessageType__c1_PR_spare6:
case NR_DL_DCCH_MessageType__c1_PR_spare5:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -207,7 +207,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
// ****************************************
// Common RX procedures subframe n
T(T_GNB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));
T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));
// if this is IF5 or 3GPP_eNB
if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
......
......@@ -886,7 +886,6 @@ static void wait_nfapi_init(char *thread_name) {
int main( int argc, char **argv )
{
crcTableInit();
int i;
#if defined (XFORMS)
//void *status;
......
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