Commit 87e25f56 authored by Michele Paffetti's avatar Michele Paffetti

adding some consideration and implement some checking based on FAPI...

 adding some consideration and implement some checking based on FAPI specifications for ndlsch path. Function for encoding, modulation ecc.. still to be added. Code Compile. 144 warnings
parent 637ab8cb
......@@ -2120,6 +2120,8 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
// generate DCIs in order of decreasing aggregation level, then common/ue spec
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization
for (L=3; L>=0; L--) {
//first common DCI
for (i=0; i<num_common_dci; i++) {
if (dci_alloc[i].L == (uint8_t)L) {
......@@ -2140,6 +2142,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
}
}
//start the second loop from the end of the previous one for ue specific DCI
for (; i<num_ue_spec_dci + num_common_dci; i++) {
if (dci_alloc[i].L == (uint8_t)L) {
......
/*******************************************************************************
*******************************************************************************/
/*! \file PHY/LTE_TRANSPORT/dci_NB_IoT.c
* \brief Top-level routines for implementing Tail-biting convolutional coding for transport channels (NPDCCH) for NB_IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SIMULATION/TOOLS/defs.h"
#include "PHY/sse_intrin.h"
#include "assertions.h"
#include "T.h"
static uint8_t d[2][3*(MAX_DCI_SIZE_BITS_NB_IOT + 16) + 96];
static uint8_t w[2][3*3*(MAX_DCI_SIZE_BITS_NB_IOT+16)];
void dci_encoding_NB_IoT(uint8_t *a[2], // Table of two DCI, even if one DCI is to transmit , the number of DCI is indicated in dci_number
uint8_t A, // Length of table a
uint16_t E, // E should equals to G (number of available bits in one RB)
uint8_t *e[2], // *e should be e[2][G]
uint16_t rnti[2], // RNTI for UE specific or common search space
uint8_t dci_number, // This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t agr_level) // Aggregation level
{
uint8_t D = (A + 16);
uint32_t RCC;
uint8_t occupation_size=1;
// encode dci
if(dci_number == 1)
{
if(agr_level == 2)
{
occupation_size=1;
}else{
occupation_size=2;
}
memset((void *)d[0],LTE_NULL,96);
ccode_encode_NB_IoT(A,2,a[0],d[0]+96,rnti[0]); // CRC attachement & Tail-biting convolutional coding
RCC = sub_block_interleaving_cc_NB_IoT(D,d[0]+96,w[0]); // Interleaving
lte_rate_matching_cc_NB_IoT(RCC,(E/occupation_size),w[0],e[0]); // Rate Matching
}else if (dci_number == 2) {
memset((void *)d[0],LTE_NULL,96);
memset((void *)d[1],LTE_NULL,96);
// first DCI encoding
ccode_encode_NB_IoT(A,2,a[0],d[0]+96,rnti[0]); // CRC attachement & Tail-biting convolutional coding
RCC = sub_block_interleaving_cc_NB_IoT(D,d[0]+96,w[0]); // interleaving
lte_rate_matching_cc_NB_IoT(RCC,E/2,w[0],e[0]); // Rate Matching , E/2 , NCCE0
// second DCI encoding
ccode_encode_NB_IoT(A,2,a[1],d[1]+96,rnti[1]); // CRC attachement & Tail-biting convolutional coding
RCC = sub_block_interleaving_cc_NB_IoT(D,d[1]+96,w[1]); // Interleaving
lte_rate_matching_cc_NB_IoT(RCC,E/2,w[1],e[1]); // Rate Matching, E/2 , NCCE1
}
}
///The scrambling sequence shall be initialised at the start of the search space and after every 4th NPDCCH subframes.
///
///
void npdcch_scrambling_NB_IoT(NB_IOT_DL_FRAME_PARMS *frame_parms,
uint8_t *e[2], // Input data
int length, // Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t Ns, // Slot number (0..19)
uint8_t dci_number, // This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t agr_level) // Aggregation level
{
int i,j,k=0;
uint32_t x1, x2, s=0;
uint8_t reset;
reset = 1;
uint8_t occupation_size=1;
if(agr_level == 2)
{
occupation_size=1;
}else{
occupation_size=2;
}
if(dci_number == 1) // Case of one DCI
{
x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell; // This is c_init in 36.211 Sec 10.2.3.1
for (i=0; i<length/occupation_size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic_NB_IoT(&x1, &x2, reset);
reset = 0;
}
e[0][k] = (e[0][k]&1) ^ ((s>>(i&0x1f))&1);
}
}else if(dci_number == 2 && occupation_size == 2) { // Case of two DCI
// Scrambling the first DCI
//
x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell; // This is c_init in 36.211 Sec 10.2.3.1
for (i=0; i<length/occupation_size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic_NB_IoT(&x1, &x2, reset);
reset = 0;
}
e[0][k] = (e[0][k]&1) ^ ((s>>(i&0x1f))&1);
}
// reset of the scrambling function
reset = 1;
// Scrambling the second DCI
//
x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 10.2.3.1
for (i=0; i<length/occupation_size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic_NB_IoT(&x1, &x2, reset);
reset = 0;
}
e[1][k] = (e[1][k]&1) ^ ((s>>(i&0x1f))&1);
}
}
}
int dci_allocate_REs_in_RB_NB_IoT(NB_IOT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0[2],
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint32_t *re_allocated, // not used variable ??!!
uint8_t dci_number, // This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t agr_level)
{
MIMO_mode_t mimo_mode = (frame_parms->mode1_flag==1)?SISO:ALAMOUTI;
uint32_t tti_offset,aa;
uint8_t re, diff_re;
int16_t gain_lin_QPSK;
uint8_t first_re,last_re;
int32_t tmp_sample1,tmp_sample2,tmp_sample3,tmp_sample4;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
first_re=0;
last_re=12;
if(agr_level == 2 && dci_number == 1)
{
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || re%3 != id_offset) // if re is not a pilot
{
// diff_re = re%3 - id_offset;
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[0][*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
}else if(agr_level == 1 && dci_number == 1){
for (re=first_re; re<6; re++) { // re varies between 0 and 6 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || re%3 != id_offset) // if re is not a pilot
{
// diff_re = re%3 - id_offset;
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[0][*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
} else {
// allocate first DCI
for (re=first_re; re<6; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || re%3 != id_offset) // if re is not a pilot
{
// diff_re = re%3 - id_offset;
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
((int16_t*)&txdataF[aa][tti_offset+6])[0] += (x0[1][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
((int16_t*)&txdataF[aa][tti_offset+6])[1] += (x0[1][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
((int16_t*)&tmp_sample3)[0] = (x0[1][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
((int16_t*)&tmp_sample3)[1] = (x0[1][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[0][*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
((int16_t*)&tmp_sample4)[0] = (x0[1][*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[0][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
((int16_t*)&tmp_sample4)[1] = (x0[1][*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[0][tti_offset+6])[0] += (int16_t)((((int16_t*)&tmp_sample3)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[0][tti_offset+6])[1] += (int16_t)((((int16_t*)&tmp_sample3)[1]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset+6])[0] += (int16_t)((((int16_t*)&tmp_sample4)[0]*ONE_OVER_SQRT2_Q15)>>15);
((int16_t*)&txdataF[1][tti_offset+6])[1] += (int16_t)((((int16_t*)&tmp_sample4)[1]*ONE_OVER_SQRT2_Q15)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
((int16_t *)&txdataF[0][tti_offset+6+1])[0] += -((int16_t *)&txdataF[1][tti_offset+6])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+6+1])[1] += ((int16_t *)&txdataF[1][tti_offset+6])[1];
((int16_t *)&txdataF[1][tti_offset+6+1])[0] += ((int16_t *)&txdataF[0][tti_offset+6])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+6+1])[1] += -((int16_t *)&txdataF[0][tti_offset+6])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
((int16_t *)&txdataF[0][tti_offset+6+2])[0] += -((int16_t *)&txdataF[1][tti_offset+6])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+6+2])[1] += ((int16_t *)&txdataF[1][tti_offset+6])[1];
((int16_t *)&txdataF[1][tti_offset+6+2])[0] += ((int16_t *)&txdataF[0][tti_offset+6])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+6+2])[1] += -((int16_t *)&txdataF[0][tti_offset+6])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
}
return(0);
}
int dci_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IOT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
uint8_t *e[2], // Input data
int G, // number of bits per subframe
unsigned short NB_IoT_RB_ID
uint8_t dci_number, // This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t agr_level) // Aggregation level
{
uint32_t jj=0;
uint32_t re_allocated,symbol_offset;
uint16_t l;
uint8_t id_offset,pilots=0;
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start, RB_IoT_ID;
re_allocated=0;
id_offset=0;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=control_region_size; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=8) || (l>=11 && l<=13))
{
pilots =1;
} else {
pilots=0;
}
id_offset = frame_parms->Nid_cell % 3; // Cell_ID_NB_IoT % 3
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(ceil(frame_parms->N_RB_DL/(float)2)));
}
symbol_offset = frame_parms->ofdm_symbol_size*l + NB_IoT_start; // symbol_offset = 512 * L + NB_IOT_RB start
dci_allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&e,
pilots,
amp,
id_offset,
&re_allocated,
dci_number,
agr_level);
}
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
return (re_allocated);
}
//*******************************************************************************************************
//*******************************************************************************************************
//********************************** Michele code *******************************************************
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
uint8_t generate_dci_top_NB(uint8_t Num_dci,
DCI_ALLOC_NB_t *dci_alloc,
int16_t amp,
NB_DL_FRAME_PARMS *fp,
//NB_IoT_eNB_NPDCCH_t npdcch,
int32_t **txdataF,
uint32_t subframe)
{
int i,L, G;
int npdcch_start_index;
/* PARAMETERS may not needed
**e_ptr : store the encoding result, and as a input to modulation
*num_pdcch_symbols : to calculate the resource allocation for pdcch
*L = aggregation level (there is 2 (at most) in NB-IoT) (Note this is not the real value but the index)
*lprime,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset,re_offset : used in the REG allocation
*gain_lin_QPSK,yseq0[Msymb],yseq1[Msymb],*y[2] : used in the modulation
*mi = used in interleaving
*e = used to store the taus sequence (taus sequence is used to generate the first sequence for DCI) Turbo coding
*wbar used in the interleaving and also REG allocation
*/
//num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe);
// generate DCIs in order of decreasing aggregation level, then common/ue spec
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization???
// Value of aggregation level (FAPI/NFAPI specs v.9.0 pag 221 value 1,2)
for (L=2; L>=1; L--) {
for (i=0; i<Num_dci; i++) {
//XXX should be checked how the scheduler store the aggregation level for NB-IoT (value 1-2 or 0-1)
if (dci_alloc[i].L == (uint8_t)L) {
if (dci_alloc[i].firstCCE>=0) {
//NB-IoT encoding
/*npdcch_encoding_NB_IoT(dci_alloc[i].dci_pdu,
frame_parms,
npdcch, //see when function dci_top is called
//no frame
subframe
//rm_stats, te_stats, i_stats
);*/
}
}
}
}
//NB-IoT scrambling
/*
*
* TS 36.213 ch 16.6.1
* npdcch_start_index indicate the starting OFDM symbol for NPDCCH in the first slot of a subframe k ad is determined as follow:
* - if eutracontrolregionsize is present (defined for in-band operating mode (mode 0,1 for FAPI specs))
* npdcch_start_index = eutracontrolregionsize (value 1,2,3) [units in number of OFDM symbol]
* -otherwise
* npdcch_start_index = 0
*
*Depending on npddch_start_index then we define different values for G
*/
//XXX the setting of this npdcch_start_index parameter should be done in the MAC
// if(fp->operating_mode == 0 || fp->operating_mode == 1) //in-band operating mode
// {
// npdcch_start_index = fp->control_region_size;
// }
// else
// {
// npdcch_start_index = 0;
// }
for(int i = 0; i <Num_dci; i++)
{
switch(dci_alloc[i].npdcch_start_symbol) //mail Bcom matthieu
{
case 0:
G = 304;
break;
case 1:
G = 240;
break;
case 2:
G = 224;
break;
case 3:
G =200;
break;
default:
LOG_E (PHY,"npdcch_start_index has unwanted value\n");
break;
}
// // NB-IoT scrambling
// npdcch_scrambling_NB_IoT(
// frame_parms,
// npdcch,
// //G,
// //q = nf mod 2 (TS 36.211 ch 10.2.3.1) with nf = number of frame
// //slot_id
// );
}
// //NB-IoT modulation
// npdcch_modulation_NB_IoT(
// txdataF,
// AMP,
// frame_parms,
// //no symbol
// //npdcch0???
// //RB_ID --> statically get from the higher layer (may included in the dl_frame params)
// );
//in NB-IoT the interleaving is done directly with the encoding procedure
//there is no interleaving because we don't apply turbo coding
// This is the REG allocation algorithm from 36-211
//already done in the modulation in our NB-IoT implementaiton??
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
//*******************************************************************************************************
return 0;
}
......@@ -46,13 +46,15 @@
//------------------------------------------------
// BCOM code functions npdcch start
// (TODO solve some error in compilation)
//------------------------------------------------
static uint8_t d[2][3*(MAX_DCI_SIZE_BITS_NB_IOT + 16) + 96];
static uint8_t w[2][3*3*(MAX_DCI_SIZE_BITS_NB_IOT+16)];
void dci_encoding_NB_IoT(uint8_t *a[2], // Table of two DCI, even if one DCI is to transmit , the number of DCI is indicated in dci_number
uint8_t A, // Length of table a
/*
void dci_encoding_NB_IoT(uint8_t *a[2], // Array of two DCI pdus, even if one DCI is to transmit , the number of DCI is indicated in dci_number
uint8_t A, // Length of array a (in number of bytes)(es 4 bytes = 32 bits) is a parameter fixed
uint16_t E, // E should equals to G (number of available bits in one RB)
uint8_t *e[2], // *e should be e[2][G]
uint16_t rnti[2], // RNTI for UE specific or common search space
......@@ -96,10 +98,10 @@ void dci_encoding_NB_IoT(uint8_t *a[2], // Table of two DCI, even if one DCI
///The scrambling sequence shall be initialised at the start of the search space and after every 4th NPDCCH subframes.
///
///
void npdcch_scrambling_NB_IoT(NB_IOT_DL_FRAME_PARMS *frame_parms,
void npdcch_scrambling_NB_IoT(NB_DL_FRAME_PARMS *frame_parms,
uint8_t *e[2], // Input data
int length, // Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t Ns, // Slot number (0..19)
uint8_t Ns,//XXX we pass the subframe // Slot number (0..19)
uint8_t dci_number, // This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t agr_level) // Aggregation level
{
......@@ -158,7 +160,7 @@ void npdcch_scrambling_NB_IoT(NB_IOT_DL_FRAME_PARMS *frame_parms,
}
int dci_allocate_REs_in_RB_NB_IoT(NB_IOT_DL_FRAME_PARMS *frame_parms,
int dci_allocate_REs_in_RB_NB_IoT(NB_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
......@@ -397,11 +399,10 @@ int dci_allocate_REs_in_RB_NB_IoT(NB_IOT_DL_FRAME_PARMS *frame_parms,
int dci_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IOT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size,//XXX we pass the npdcch_start_symbol // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
uint8_t *e[2], // Input data
int G, // number of bits per subframe
unsigned short NB_IoT_RB_ID,
uint8_t dci_number, // This variable should takes the 1 or 2 (1 for in case of one DCI, 2 in case of two DCI)
uint8_t agr_level) // Aggregation level
{
......@@ -415,7 +416,7 @@ int dci_modulation_NB_IoT(int32_t **txdataF,
id_offset=0;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
RB_IoT_ID = frame_parms->NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=control_region_size; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=8) || (l>=11 && l<=13))
......@@ -448,7 +449,7 @@ int dci_modulation_NB_IoT(int32_t **txdataF,
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
return (re_allocated);
}
*/
//------------------------------------------------
// BCOM code functions npdcch end
//------------------------------------------------
......@@ -456,18 +457,23 @@ int dci_modulation_NB_IoT(int32_t **txdataF,
uint8_t generate_dci_top_NB(uint8_t Num_dci,
uint8_t generate_dci_top_NB(
NB_IoT_eNB_NPDCCH_t* npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_t *dci_alloc,
int16_t amp,
NB_DL_FRAME_PARMS *fp,
//NB_IoT_eNB_NPDCCH_t npdcch,
int32_t **txdataF,
uint32_t subframe)
uint32_t subframe,
uint8_t npdcch_start_symbol)
{
int i,L, G;
int npdcch_start_index = dci_alloc->npdcch_start_symbol;
int i, G;
//temporary variable
uint16_t rnti[2];
uint8_t L = 0;
/* PARAMETERS may not needed
**e_ptr : store the encoding result, and as a input to modulation
......@@ -480,118 +486,104 @@ uint8_t generate_dci_top_NB(uint8_t Num_dci,
*wbar used in the interleaving and also REG allocation
*/
//num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe);
// generate DCIs in order of decreasing aggregation level, then common/ue spec
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization???
// Value of aggregation level (FAPI/NFAPI specs v.9.0 pag 221 value 1,2)
for (L=2; L>=1; L--) {
for (i=0; i<Num_dci; i++) {
/*
* in NB-IoT we can have at most 2 aggregation level since we have only 2 NCCE (Narrowband control channel element)
* if only 1 DCI transmitted:
* - Aggregation level could be 1 or 2
* if 2 DCI transmitted:
* - Aggregation level should be 1
*
*/
//XXX should be checked how the scheduler store the aggregation level for NB-IoT (value 1-2 or 0-1)
if (dci_alloc[i].L == (uint8_t)L) {
//First take all the DCI pdu and their corrispondent rnti
for(i = 0; i<Num_dci;i++)
{
npdcch->a[i]=dci_alloc[i].dci_pdu;
rnti[i]=dci_alloc[i].rnti;
L = dci_alloc[i].L;
if (dci_alloc[i].firstCCE>=0) {
}
if(Num_dci == 2 && L == 1)
LOG_E(PHY,"generate_dci_top_NB: Aggregation level not compatible with Num_dci\n" );
//NB-IoT encoding
/*npdcch_encoding_NB_IoT(dci_alloc[i].dci_pdu,
frame_parms,
npdcch, //see when function dci_top is called
//no frame
subframe
//rm_stats, te_stats, i_stats
);*/
}
}
}
//Second, evaluate the G variable based of the npdcch_start_sysmbol
}
//NB-IoT scrambling
/*
*
* TS 36.213 ch 16.6.1
* npdcch_start_index indicate the starting OFDM symbol for NPDCCH in the first slot of a subframe k ad is determined as follow:
* npdcch_start_symbol indicate the starting OFDM symbol for NPDCCH in the first slot of a subframe k ad is determined as follow:
* - if eutracontrolregionsize is present (defined for in-band operating mode (mode 0,1 for FAPI specs))
* npdcch_start_index = eutracontrolregionsize (value 1,2,3) [units in number of OFDM symbol]
* npdcch_start_symbol = eutracontrolregionsize (value 1,2,3) [units in number of OFDM symbol]
* -otherwise
* npdcch_start_index = 0
* npdcch_start_symbol = 0
*
*XXX npdcch_start symbol should be the same for every DCI once is decided since depends on the parameters
*(the setting of this npdcch_start_symbol parameter should be done in the MAC)
*Depending on npdcch_start_symbol then we define different values for G
*
*Depending on npddch_start_index then we define different values for G
*/
//XXX the setting of this npdcch_start_index parameter should be done in the MAC
// if(fp->operating_mode == 0 || fp->operating_mode == 1) //in-band operating mode
// {
// npdcch_start_index = fp->control_region_size;
// }
// else
// {
// npdcch_start_index = 0;
// }
for(int i = 0; i <Num_dci; i++)
{
switch(dci_alloc[i].npdcch_start_symbol) //mail Bcom matthieu
{
case 0:
G = 304;
break;
case 1:
G = 240;
break;
case 2:
G = 224;
break;
case 3:
G =200;
break;
default:
LOG_E (PHY,"npdcch_start_index has unwanted value\n");
break;
}
// // NB-IoT scrambling
// npdcch_scrambling_NB_IoT(
// frame_parms,
// npdcch,
// //G,
// //q = nf mod 2 (TS 36.211 ch 10.2.3.1) with nf = number of frame
// //slot_id
// );
switch(npdcch_start_symbol) //mail Bcom matthieu
{
case 0:
G = 304;
break;
case 1:
G = 240;
break;
case 2:
G = 224;
break;
case 3:
G =200;
break;
default:
LOG_E (PHY,"npdcch_start_symbol has unwanted value\n");
break;
}
//NB-IoT encoding
// dci_encoding_NB_IoT(
// a,
// 4, // total length (in byte) of a [assume max 2 pdus of ??]
// G,
// npdcch->e,
// rnti,
// Num_dci,
// L
// );
// //NB-IoT modulation
// npdcch_modulation_NB_IoT(
// txdataF,
// AMP,
// frame_parms,
// //no symbol
// //npdcch0???
// //RB_ID --> statically get from the higher layer (may included in the dl_frame params)
// );
//NB-IoT scrambling
// npdcch_scrambling_NB_IoT(
// fp,
// npdcch->e,
// G,
// subframe,
// Num_dci,
// L
// );
//NB-IoT Modulation
// dci_modulation_NB_IoT(
// txdataF,
// amp,
// fp,
// npdcch_start_symbol,
// npdcch->e,
// G,
// Num_dci,
// L
// );
//in NB-IoT the interleaving is done directly with the encoding procedure
//there is no interleaving because we don't apply turbo coding
// This is the REG allocation algorithm from 36-211
//already done in the modulation in our NB-IoT implementaiton??
return 0;
}
......@@ -42,7 +42,7 @@ typedef enum
{
DCIFormatN0 = 0,
DCIFormatN1,
DCIFormatN1_RA,
DCIFormatN1_RA,//is for initial RA procedure (semi-static information) so maybe is not needed
DCIFormatN1_RAR,
DCIFormatN2,
DCIFormatN2_Ind,
......@@ -288,4 +288,4 @@ typedef struct DCIN2_Pag DCIN2_Pag_t;
#define MAX_DCI_SIZE_BITS_NB_IOT 23
#endif
\ No newline at end of file
#endif
......@@ -56,7 +56,7 @@ void NB_add_dci(DCI_PDU_NB *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L = aggregation;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti = rnti;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format = dci_fmt;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].npdcch_start_symbol = npdcch_start_symbol;
DCI_pdu->npdcch_start_symbol = npdcch_start_symbol;
DCI_pdu->Num_dci++;
......@@ -122,7 +122,6 @@ int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
((DCIN0_t *)ULSCH_DCI_NB)->ndi =ndi;
((DCIN0_t *)ULSCH_DCI_NB)->DCIRep =DCIRep;
eNB->DCI_pdu->Num_dci++;
NB_add_dci(eNB->DCI_pdu,ULSCH_DCI_NB,rnti,sizeof(DCIN0_t),aggregation,sizeof_DCIN0_t,DCIFormatN0, npdcch_start_symbol);
......@@ -160,6 +159,7 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
eNB->DCI_pdu = (DCI_PDU_NB*) malloc(sizeof(DCI_PDU_NB));
//N1 parameters
/// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
......@@ -229,8 +229,8 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
/*Now configure the ndlsch structure*/
ndlsch->subframe_tx[subframe] = 1; // check if it's OK
ndlsch->rnti = rnti;
ndlsch->active = 1;
ndlsch->rnti = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlsch->active = 0; //will be activated by the corresponding NDSLCH pdu
// use this value to configure PHY both harq_processes and resource mapping.
ndlsch_harq->scheduling_delay = Sched_delay;
......@@ -248,8 +248,7 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
* ISF = ResAssign
*/
ndlsch_harq->TBS = TBStable_NB_IoT[mcs][ResAssign]; // this table should be rewritten for nb-iot
ndlsch_harq->frame = frame;
ndlsch_harq->TBS = TBStable_NB_IoT[mcs][ResAssign];
ndlsch_harq->subframe = subframe;
//ndlsch_harq->B; we don-t have now my is given when we receive the dlsch data
......@@ -299,6 +298,8 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
/*Now configure the ndlsch structure*/
ndlsch->subframe_tx[subframe] = 1; // check if it's OK
ndlsch->rnti = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlsch->active = 0;//will be activated by the corresponding NDSLCH pdu
// use this value to configure PHY both harq_processes and resource mapping.
ndlsch_harq->scheduling_delay = Sched_delay;
......
......@@ -818,14 +818,24 @@ typedef enum
}ndlsch_flag_t;
typedef struct {
//array containing the pdus of DCI
uint8_t *a[2];
//Array containing encoded DCI data
uint8_t *e[2];
}NB_IoT_eNB_NPDCCH_t;
typedef struct {
///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission
/// see FAPI/NFAPI specs Table 4-121
uint8_t npdcch_start_symbol;
/// Length of DCI in bits
uint8_t dci_length;
/// Aggregation level only 0,1 in NB-IoT
/// Aggregation level only 1,2 in NB-IoT
uint8_t L;
/// Position of first CCE of the dci
int firstCCE;
......@@ -842,6 +852,9 @@ typedef struct {
typedef struct {
//delete the count for the DCI numbers,NUM_DCI_MAX should set to 2
uint32_t num_npdcch_symbols;
///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission
/// see FAPI/NFAPI specs Table 4-45
uint8_t npdcch_start_symbol;
uint8_t Num_dci;
DCI_ALLOC_NB_t dci_alloc[2] ;
} DCI_PDU_NB;
......@@ -882,6 +895,8 @@ typedef struct {
uint8_t mcs;
// we don't have code block segmentation / crc attachment / concatenation in NB-IoT R13 36.212 6.4.2
// we don't have beamforming in NB-IoT
//this index will be used mainly for SI message buffer
uint8_t pdu_buffer_index;
} NB_IoT_DL_eNB_HARQ_t;
......
......@@ -92,7 +92,7 @@ void npbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
/*Function to pack the DCI*/
void NB_add_dci(DCI_PDU_NB *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt, uint8_t npdcch_start_symbol);
/*Use the UL DCI Information to configure PHY and also Packed*/
/*Use the UL DCI Information to configure PHY and also Pack the DCI*/
int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
DCI_CONTENT *DCI_Content,
......@@ -102,7 +102,7 @@ int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
uint8_t aggregation,
uint8_t npdcch_start_symbol
);
/*Use the DL DCI Information to configure PHY and also Packed*/
/*Use the DL DCI Information to configure PHY and also Pack the DCI*/
int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
int frame,
uint8_t subframe,
......@@ -115,5 +115,17 @@ int NB_generate_eNB_dlsch_params_from_dci(PHY_VARS_eNB *eNB,
uint8_t npdcch_start_symbol
);
/*Function for DCI encoding, scrambling, modulation*/
uint8_t generate_dci_top_NB(
NB_IoT_eNB_NPDCCH_t* npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_t *dci_alloc,
int16_t amp,
NB_DL_FRAME_PARMS *fp,
int32_t **txdataF,
uint32_t subframe,
uint8_t npdcch_start_symbol);
#endif
......@@ -703,7 +703,7 @@ typedef struct PHY_VARS_eNB_s {
*/
NB_IoT_eNB_NPBCH *npbch;
//NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT]; //check the max size of this array
NB_IoT_eNB_NPDCCH_t *npdcch; //check if should be an array and the max size of this array
NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT];
NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR
NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1;
......
......@@ -152,6 +152,13 @@ typedef struct {
} DL_GapConfig_NB;
typedef struct {
/// Number of resource blocks (RB) in DL of the LTE (for knowing the bandwidth)
uint8_t N_RB_DL;
/// Number of resource blocks (RB) in UL of the LTE ((for knowing the bandwidth)
uint8_t N_RB_UL;
/// Cell ID
uint16_t Nid_cell;
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
......@@ -226,8 +233,6 @@ typedef struct {
// CE level to determine the NPRACH Configuration (one CE for each NPRACH config.)
uint8_t CE;
/*
* index of the PRB assigned to NB-IoT carrier in in-band/guard-band operating mode
*/
......
......@@ -123,6 +123,7 @@ void handle_nfapi_dlsch_pdu_NB(PHY_VARS_eNB *eNB,
{
eNB->ndlsch_ra->harq_process->pdu = sdu;
eNB->ndlsch_ra->npdsch_start_symbol = rel13->start_symbol;
eNB->ndlsch_ra->active = 1;
}
else
{ //this for ue data
......@@ -137,8 +138,11 @@ void handle_nfapi_dlsch_pdu_NB(PHY_VARS_eNB *eNB,
ndlsch = eNB->ndlsch[(uint8_t)UE_id];
ndlsch_harq = eNB->ndlsch[(uint8_t)UE_id]->harq_process;
AssertFatal(ndlsch_harq!=NULL,"dlsch_harq for ue specific is null\n");
ndlsch->npdsch_start_symbol = rel13->start_symbol;
ndlsch_harq->pdu = sdu;
ndlsch->active = 1;
}
}
......@@ -152,6 +156,11 @@ void handle_nfapi_dlsch_pdu_NB(PHY_VARS_eNB *eNB,
/////////////////////////////////////////////////////////////////////////////////////////////////
//Memo for initialization TODO: target/SIMU/USER/init_lte.c/init_lte_eNB --> new_eNB_dlsch(..) //
//this is where the allocation of PHy_vars_eNB and all the ndlsch structures happen //
/////////////////////////////////////////////////////////////////////////////////////////////////
// do the schedule response and trigger the TX
void schedule_response(Sched_Rsp_t *Sched_INFO)
......@@ -211,7 +220,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
for (i=0;i<number_dl_pdu;i++) //in principle this should be always = 1
for (i=0;i<number_dl_pdu;i++) //in principle this should be at most 2 (in case of DCI)
{
dl_config_pdu = &DL_req->dl_config_pdu_list[i];
switch (dl_config_pdu->pdu_type)
......@@ -235,7 +244,16 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
break;
case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
//we can have three types of NDLSCH based on our assumptions: SIB1, SI, Data, RAR
//remember that SI messages have no DCI in NB-IoT therefore this is the only way to configure the ndlsch_SI/ndlsch_SIB1 structure
//remember that SI messages have no DCI in NB-IoT therefore this is the only way to configure the ndlsch_SI/ndlsch_SIB1 structures ndlsch->active = 1;
/*
* OBSERVATION:
* Although 2 DCI may be received over a schedule_response the transmission of the NDLSCH data foresees only 1 NDLSCH PDU at time.
* Therefore is the MAC scheduler that knowing the different timing delay will send the corresponding schedule_response containing the NDLSCH PDU and the MAC PDU
* at the proper DL subframe
* -for this reason the activation of the ndslch structure is done only when we receive the NDLSCH pdu (here) such the in the TX procedure only 1 ue-specific pdu
* result active from the loop before calling the ndlsch_procedure
*/
handle_nfapi_dlsch_pdu_NB(eNB, proc,dl_config_pdu,Sched_INFO->sdu[i]);
......
......@@ -376,6 +376,7 @@ uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1);
int8_t find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
//NB-IoT
int8_t find_ue_NB(uint16_t rnti, PHY_VARS_eNB *eNB);
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rnti);
......
......@@ -487,24 +487,19 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
DCI_format_NB_t DCI_format;
NB_IoT_eNB_NDLSCH_t *ndlsch;
DCI_Content = (DCI_CONTENT*) malloc(sizeof(DCI_CONTENT));
// In NB-IoT, there is no DCI for SI, we might use the scheduling infomation from SIB1-NB to get the phyical layer configuration.
//mapping the fapi parameters to the oai parameters
// check DCI format is N1 (format 0) or N2 (format 1)
// check DCI format is N1 (format 0)
if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_format == 0)
{
//check DCI format N1 is for RAR rnti_type in FAPI specs table 4-45
if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti_type == 1)
{
DCI_format = DCIFormatN1_RAR;
ndlsch= eNB->ndlsch_ra;//we store the RNTI for the RAR
ndlsch->ndlsch_type = RAR;
//mapping the fapi parameters to the oai parameters
DCI_format = DCIFormatN1_RAR;
//DCI format N1 to RAR
DCI_Content->DCIN1_RAR.type = 1;
......@@ -519,7 +514,11 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
// fill the dlsch_ra_NB sructure for RAR, and packed the DCI PDU
LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");
ndlsch= eNB->ndlsch_ra;
ndlsch->ndlsch_type = RAR;
LOG_D(PHY,"Generating dlsch params for RA_RNTI and packing DCI\n");
NB_generate_eNB_dlsch_params_from_dci(eNB,
frame,
subframe,
......@@ -539,10 +538,12 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
//TODO target/SIMU/USER?init_lte/init_lte_eNB we should allocate the ndlsch structures
UE_id = find_ue_NB(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti, eNB);
AssertFatal(UE_id == -1, "no ndlsch context available or no ndlsch context corresponding to that rnti\n");
AssertFatal(UE_id != -1, "no ndlsch context available or no ndlsch context corresponding to that rnti\n");
ndlsch = eNB->ndlsch[(uint8_t)UE_id]; //in the old implementation they also consider UE_id = 1;
ndlsch->ndlsch_type = UE_Data;
//mapping the fapi parameters to the oai parameters
DCI_format = DCIFormatN1;
//DCI format N1 to DLSCH
DCI_Content->DCIN1.type = 1;
......@@ -555,8 +556,14 @@ void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,nfapi
DCI_Content->DCIN1.HARQackRes = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource;
DCI_Content->DCIN1.DCIRep = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number;
//fill the ndlsch structure for UE
//fill the ndlsch structure for UE and packed the DCI PD
ndlsch = eNB->ndlsch[(uint8_t)UE_id]; //in the old implementation they also consider UE_id = 1;
ndlsch->ndlsch_type = UE_Data;
//parameters we don't consider pdsch config dedicated since not calling the phy config dedicated step2
LOG_D(PHY,"Generating dlsch params for DCIN1 data and packing DCI\n");
NB_generate_eNB_dlsch_params_from_dci(eNB,
frame,
subframe,
......@@ -1041,12 +1048,13 @@ void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
*
*
*XXX important: set the flag HARQ process->status to DISABLE when PHY finished the SI-transmission over the 2 or 8 subframes
*XXX important: whenever we enter for some error in the ndlsch_procedure with a pdu that is NULL but all the data of the SI have been transmitted --> generate error
*XXX : the npdlsch_procedure in this case should be only called when is triggered by the MAC schedule_response (use the status flag set by the schedule_response)
*XXX important: whenever we enter for some error in the ndlsch_procedure with a pdu that is NULL but all the data of the SI have been transmitted (pdu_buffer_index = 0)
*XXX --> generate error
*XXX: the npdlsch_procedure in this case should be only called when is triggered by the MAC schedule_response (use the status flag set by the schedule_response)
*
*/
if(eNB->ndlsch_SI->harq_process->status == ACTIVE && (eNB->ndlsch_SI->harq_process->status != ACTIVE || subframe != 4)) //condition on SIB1-NB
if(eNB->ndlsch_SI->harq_process->status == ACTIVE && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE || subframe != 4)) //condition on SIB1-NB
{
if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
{
......@@ -1078,31 +1086,79 @@ void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
}
///check for RAR transmission
if(eNB->ndlsch_ra != NULL && eNB->ndlsch_ra->active == 1)
if(eNB->ndlsch_ra != NULL && eNB->ndlsch_ra->active == 1 && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE || subframe != 4)) //condition on SIB1-NB
{
if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5 && subframe != 9)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
eNB->ndlsch_ra->harq_process->pdu);
npdsch_procedures(eNB,
proc,
eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
eNB->ndlsch_ra->harq_process->pdu);
eNB->ndlsch_ra->active= 0;
//it should be activated only when we receive the proper DCIN1_RAR
eNB->ndlsch_ra->active= 0;
}
}
else //this frame not foresee the transmission of NSSS (subframe 9 is available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
eNB->ndlsch_ra->harq_process->pdu);
}
//it should be activated only when we receive the proper DCIN1_RAR
eNB->ndlsch_ra->active= 0; // maybe this is already done inside the ndlsch_procedure
}
}
}
/*
* Delays between DCI transmission and NDLSCH transmission are taken in consideration by the MAC scheduler by sending in the proper subframe the scheduler_response
* Transmission over more subframe and Repetitions are managed directly by the PHY layer
* We should have only 1 ue-specific ndlsch structure active at each time (active flag is set = 1 only at the corresponding NDLSCH pdu reception and not at the DCI time
* (NDLSCH transmission should be compliant with the FAPI procedure Figure 3-49)
*
* XXX how are managed the transmission and repetitions???
*
*/
//transmission of UE specific ndlsch data
//this should give only 1 result (since only 1 ndlsch procedure is activated at once) so we brak after the transmission
for (int UE_id = 0; i < NUMBER_OF_UE_MAX_NB_IoT; UE_id++)
{
if(eNB->ndlsch[(uint8_t)UE_id] != NULL && eNB->ndlsch[(uint8_t)UE_id]->active == 1)
if(eNB->ndlsch[(uint8_t)UE_id] != NULL && eNB->ndlsch[(uint8_t)UE_id]->active == 1 && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE || subframe != 4)) //condition on sib1-NB
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch[(uint8_t)UE_id],
eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5 && subframe != 9)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch[(uint8_t)UE_id],
eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
break;
}
}
else //this frame not foresee the transmission of NSSS (subframe 9 is available)
{
if(eNB->ndlsch_SI != NULL && subframe!= 0 && subframe != 5)
{
npdsch_procedures(eNB,
proc,
eNB->ndlsch[(uint8_t)UE_id],
eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
break;
}
}
}
//we don't care about subframe TX for the PUCCH since not defined by NB-IoT
......@@ -1114,11 +1170,13 @@ void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
/*If we have DCI to generate do it now*/
generate_dci_top_NB(
eNB->npdcch,
dci_pdu->Num_dci,
dci_pdu->dci_alloc,
AMP,
fp,
eNB->common_vars.txdataF[0],
subframe);
subframe,
dci_pdu->npdcch_start_symbol); //this parameter depends by eutraControlRegionSize (see TS36.213 16.6.1)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment