SC-FDMA working for 1 SNR loop (enabled using "NR_SC_FDMA" MACRO)
- Added nr_dft at UE side and nr_idft at gNB side - NR_SC_FDMA can be found in "PHY/defs_nr_common.h" - For 1 SNR loop, the code executes correctly - For more loops, it gives a segmentation fault in the LDPC decoder - The segmentation fault is caused when nr_idft is used - The code works fine when the "NR_SC_FDMA" is disabled
This commit is contained in:
committed by
Thomas Schlichter
parent
d34868e693
commit
02e329a35d
@@ -119,4 +119,183 @@ void nr_layer_mapping(int16_t **mod_symbs,
|
|||||||
default:
|
default:
|
||||||
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
|
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
__m128i dft_in128[1][1200], dft_out128[1][1200];
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int16x8_t dft_in128[1][1200], dft_out128[1][1200];
|
||||||
|
#endif
|
||||||
|
uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0];
|
||||||
|
|
||||||
|
uint32_t i, ip;
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
__m128i norm128;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int16x8_t norm128;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
|
||||||
|
dft_in0[ip] = d[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Msc_PUSCH) {
|
||||||
|
case 12:
|
||||||
|
dft12((int16_t *)dft_in0, (int16_t *)dft_out0);
|
||||||
|
|
||||||
|
#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);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
((int16x8_t*)dft_out0)[i] = vqdmulhq_s16(((int16x8_t*)dft_out0)[i], norm128);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
dft24((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 36:
|
||||||
|
dft36((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 48:
|
||||||
|
dft48((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 60:
|
||||||
|
dft60((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 72:
|
||||||
|
dft72((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 96:
|
||||||
|
dft96((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 108:
|
||||||
|
dft108((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 120:
|
||||||
|
dft120((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 144:
|
||||||
|
dft144((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 180:
|
||||||
|
dft180((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 192:
|
||||||
|
dft192((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 216:
|
||||||
|
dft216((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 240:
|
||||||
|
dft240((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 288:
|
||||||
|
dft288((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 300:
|
||||||
|
dft300((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 324:
|
||||||
|
dft324((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 360:
|
||||||
|
dft360((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 384:
|
||||||
|
dft384((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 432:
|
||||||
|
dft432((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 480:
|
||||||
|
dft480((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 540:
|
||||||
|
dft540((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 576:
|
||||||
|
dft576((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 600:
|
||||||
|
dft600((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 648:
|
||||||
|
dft648((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 720:
|
||||||
|
dft720((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 768:
|
||||||
|
dft768((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 864:
|
||||||
|
dft864((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 900:
|
||||||
|
dft900((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 960:
|
||||||
|
dft960((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 972:
|
||||||
|
dft972((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1080:
|
||||||
|
dft1080((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1152:
|
||||||
|
dft1152((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1200:
|
||||||
|
dft1200((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
|
||||||
|
z[i] = dft_out0[ip];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -68,4 +68,12 @@ int nr_slot_fep_ul(PHY_VARS_gNB *phy_vars_gNB,
|
|||||||
int sample_offset,
|
int sample_offset,
|
||||||
int no_prefix);
|
int no_prefix);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief This function implements the dft transform precoding in PUSCH
|
||||||
|
\param z Pointer to output in frequnecy domain
|
||||||
|
\param d Pointer to input in time domain
|
||||||
|
\param Msc_PUSCH number of allocated data subcarriers
|
||||||
|
*/
|
||||||
|
void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -73,6 +73,12 @@ void nr_ulsch_extract_rbs_single(int **rxdataF,
|
|||||||
unsigned short nb_rb_pusch,
|
unsigned short nb_rb_pusch,
|
||||||
NR_DL_FRAME_PARMS *frame_parms);
|
NR_DL_FRAME_PARMS *frame_parms);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief This function implements the idft transform precoding in PUSCH
|
||||||
|
\param z Pointer to input in frequnecy domain, and it is also the output in time domain
|
||||||
|
\param Msc_PUSCH number of allocated data subcarriers
|
||||||
|
*/
|
||||||
|
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH);
|
||||||
|
|
||||||
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
|
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
|
||||||
@param rxdataF_comp Compensated channel output
|
@param rxdataF_comp Compensated channel output
|
||||||
|
|||||||
@@ -2,7 +2,219 @@
|
|||||||
#include "nr_transport_proto.h"
|
#include "nr_transport_proto.h"
|
||||||
#include "PHY/impl_defs_top.h"
|
#include "PHY/impl_defs_top.h"
|
||||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||||
|
#include "PHY/defs_nr_common.h"
|
||||||
|
|
||||||
|
short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
||||||
|
|
||||||
|
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
__m128i idft_in128[1][1200], idft_out128[1][1200];
|
||||||
|
__m128i norm128;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int16x8_t idft_in128[1][1200], idft_out128[1][1200];
|
||||||
|
int16x8_t norm128;
|
||||||
|
#endif
|
||||||
|
int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0];
|
||||||
|
|
||||||
|
int i, ip;
|
||||||
|
|
||||||
|
LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
|
||||||
|
|
||||||
|
// conjugate input
|
||||||
|
for (i = 0; i < (Msc_PUSCH>>2); i++) {
|
||||||
|
#if defined(__x86_64__)||defined(__i386__)
|
||||||
|
*&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
*&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0,ip=0; i<Msc_PUSCH; i++, ip+=4) {
|
||||||
|
((uint32_t*)idft_in0)[ip+0] = z[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch (Msc_PUSCH) {
|
||||||
|
case 12:
|
||||||
|
dft12((int16_t *)idft_in0, (int16_t *)idft_out0);
|
||||||
|
|
||||||
|
#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*)idft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)idft_out0)[i], norm128), 1);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
((int16x8_t*)idft_out0)[i] = vqdmulhq_s16(((int16x8_t*)idft_out0)[i], norm128);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
dft24(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 36:
|
||||||
|
dft36(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 48:
|
||||||
|
dft48(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 60:
|
||||||
|
dft60(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 72:
|
||||||
|
dft72(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 96:
|
||||||
|
dft96(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 108:
|
||||||
|
dft108(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 120:
|
||||||
|
dft120(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 144:
|
||||||
|
dft144(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 180:
|
||||||
|
dft180(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 192:
|
||||||
|
dft192(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 216:
|
||||||
|
dft216(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 240:
|
||||||
|
dft240(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 288:
|
||||||
|
dft288(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 300:
|
||||||
|
dft300(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 324:
|
||||||
|
dft324((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 360:
|
||||||
|
dft360((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 384:
|
||||||
|
dft384((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 432:
|
||||||
|
dft432((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 480:
|
||||||
|
dft480((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 540:
|
||||||
|
dft540((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 576:
|
||||||
|
dft576((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 600:
|
||||||
|
dft600((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 648:
|
||||||
|
dft648((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 720:
|
||||||
|
dft720((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 768:
|
||||||
|
dft768((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 864:
|
||||||
|
dft864((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 900:
|
||||||
|
dft900((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 960:
|
||||||
|
dft960((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 972:
|
||||||
|
dft972((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1080:
|
||||||
|
dft1080((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1152:
|
||||||
|
dft1152((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1200:
|
||||||
|
dft1200(idft_in0, idft_out0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// should not be reached
|
||||||
|
LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
|
||||||
|
z[i] = ((uint32_t*)idft_out0)[ip];
|
||||||
|
}
|
||||||
|
|
||||||
|
// conjugate output
|
||||||
|
for (i = 0; i < (Msc_PUSCH>>2); i++) {
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
*&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
_mm_empty();
|
||||||
|
_m_empty();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void nr_ulsch_extract_rbs_single(int **rxdataF,
|
void nr_ulsch_extract_rbs_single(int **rxdataF,
|
||||||
int **rxdataF_ext,
|
int **rxdataF_ext,
|
||||||
@@ -51,18 +263,18 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
|||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
unsigned char harq_pid)
|
unsigned char harq_pid)
|
||||||
{
|
{
|
||||||
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||||
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
|
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
|
||||||
uint32_t nb_re;
|
uint32_t nb_re_pusch;
|
||||||
|
|
||||||
if(symbol == rel15_ul->start_symbol)
|
if(symbol == rel15_ul->start_symbol)
|
||||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
|
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
|
||||||
|
|
||||||
if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
|
if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
|
||||||
nb_re = rel15_ul->number_rbs * 6;
|
nb_re_pusch = rel15_ul->number_rbs * 6;
|
||||||
else
|
else
|
||||||
nb_re = rel15_ul->number_rbs * 12;
|
nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
//--------------------- RBs extraction ---------------------
|
//--------------------- RBs extraction ---------------------
|
||||||
@@ -76,8 +288,11 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
|||||||
rel15_ul->start_rb,
|
rel15_ul->start_rb,
|
||||||
rel15_ul->number_rbs,
|
rel15_ul->number_rbs,
|
||||||
frame_parms);
|
frame_parms);
|
||||||
|
|
||||||
|
#ifdef NR_SC_FDMA
|
||||||
|
nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[gNB->pusch_vars[UE_id]->rxdataF_ext_offset], nb_re_pusch);
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
//-------------------- LLRs computation --------------------
|
//-------------------- LLRs computation --------------------
|
||||||
//----------------------------------------------------------
|
//----------------------------------------------------------
|
||||||
@@ -86,10 +301,10 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
|
|||||||
gNB->pusch_vars[UE_id]->ul_ch_mag,
|
gNB->pusch_vars[UE_id]->ul_ch_mag,
|
||||||
gNB->pusch_vars[UE_id]->ul_ch_magb,
|
gNB->pusch_vars[UE_id]->ul_ch_magb,
|
||||||
&gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
|
&gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
|
||||||
nb_re,
|
nb_re_pusch,
|
||||||
symbol,
|
symbol,
|
||||||
rel15_ul->Qm);
|
rel15_ul->Qm);
|
||||||
|
|
||||||
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re;
|
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1082,10 +1082,6 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
|
|||||||
uint32_t n_RNTI,
|
uint32_t n_RNTI,
|
||||||
uint32_t* out);
|
uint32_t* out);
|
||||||
|
|
||||||
void pusch_transform_precoding(NR_UE_ULSCH_t *ulsch,
|
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
|
||||||
int harq_pid);
|
|
||||||
|
|
||||||
/** \brief Perform the following functionalities:
|
/** \brief Perform the following functionalities:
|
||||||
- encoding
|
- encoding
|
||||||
- scrambling
|
- scrambling
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ typedef struct {
|
|||||||
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||||
uint32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
|
uint32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
|
||||||
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
|
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
|
||||||
uint32_t y[MAX_NUM_NR_RE];
|
uint32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
|
||||||
/*
|
/*
|
||||||
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||||
uint8_t q[MAX_CQI_PAYLOAD];
|
uint8_t q[MAX_CQI_PAYLOAD];
|
||||||
|
|||||||
@@ -41,11 +41,6 @@
|
|||||||
|
|
||||||
//#define DEBUG_SCFDMA
|
//#define DEBUG_SCFDMA
|
||||||
|
|
||||||
#ifdef DEBUG_SCFDMA
|
|
||||||
|
|
||||||
FILE *debug_scfdma;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
|
int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
|
||||||
uint8_t thread_id,
|
uint8_t thread_id,
|
||||||
@@ -152,105 +147,6 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pusch_transform_precoding(NR_UE_ULSCH_t *ulsch, NR_DL_FRAME_PARMS *frame_parms, int harq_pid){
|
|
||||||
|
|
||||||
NR_UL_UE_HARQ_t *harq_process;
|
|
||||||
int x[8192]__attribute__ ((aligned (32))); // 8192 is the maximum number of fft bins
|
|
||||||
uint32_t *dmod;
|
|
||||||
int sc, pusch_symb, pusch_sc;
|
|
||||||
int symb, k, l, num_mod_symb;
|
|
||||||
|
|
||||||
harq_process = ulsch->harq_processes[harq_pid];
|
|
||||||
|
|
||||||
#ifdef DEBUG_SCFDMA
|
|
||||||
debug_scfdma = fopen("debug_scfdma.txt","w");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dmod = ulsch->d_mod;
|
|
||||||
pusch_symb = ulsch->Nsymb_pusch;
|
|
||||||
pusch_sc = ulsch->Nsc_pusch;
|
|
||||||
num_mod_symb = harq_process->num_of_mod_symbols;
|
|
||||||
|
|
||||||
void (*dft)(int16_t *,int16_t *, int);
|
|
||||||
|
|
||||||
switch (frame_parms->ofdm_symbol_size) {
|
|
||||||
case 128:
|
|
||||||
dft = dft128;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 256:
|
|
||||||
dft = dft256;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 512:
|
|
||||||
dft = dft512;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1024:
|
|
||||||
dft = dft1024;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1536:
|
|
||||||
dft = dft1536;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2048:
|
|
||||||
dft = dft2048;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4096:
|
|
||||||
dft = dft4096;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8192:
|
|
||||||
dft = dft8192;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
dft = dft512;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
symb = 0;
|
|
||||||
|
|
||||||
for(l = 0; l < pusch_symb; l++){
|
|
||||||
|
|
||||||
for (sc = 0; sc < pusch_sc; sc++){
|
|
||||||
|
|
||||||
((int16_t *)x)[sc*2] = (symb<num_mod_symb)?(AMP*((int16_t *)dmod)[symb*2])>>15:0;
|
|
||||||
((int16_t *)x)[sc*2 + 1] = (symb<num_mod_symb)?(AMP*((int16_t *)dmod)[symb*2 + 1])>>15:0;
|
|
||||||
|
|
||||||
#ifdef DEBUG_SCFDMA
|
|
||||||
fprintf(debug_scfdma, "x[%d] = %d\n", symb*2, ((int16_t *)x)[sc*2] );
|
|
||||||
fprintf(debug_scfdma, "x[%d] = %d\n", symb*2 + 1, ((int16_t *)x)[sc*2 + 1] );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
symb++;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dft((int16_t *)x, (int16_t *)&ulsch->y[l*pusch_sc], 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG_SCFDMA
|
|
||||||
|
|
||||||
for (symb = 0; symb < num_mod_symb; symb++)
|
|
||||||
{
|
|
||||||
fprintf(debug_scfdma, "ulsch->y[%d] = %d\n", symb*2, ((int16_t *)ulsch->y)[symb*2] );
|
|
||||||
fprintf(debug_scfdma, "ulsch->y[%d] = %d\n", symb*2 + 1, ((int16_t *)ulsch->y)[symb*2 + 1] );
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(debug_scfdma);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||||
unsigned char harq_pid,
|
unsigned char harq_pid,
|
||||||
uint8_t slot,
|
uint8_t slot,
|
||||||
@@ -327,7 +223,7 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
mod_order,
|
mod_order,
|
||||||
(int16_t *)ulsch_ue->d_mod);
|
(int16_t *)ulsch_ue->d_mod);
|
||||||
|
|
||||||
pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid);
|
// pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid);
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -365,11 +261,46 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
harq_process_ul_ue->Nl,
|
harq_process_ul_ue->Nl,
|
||||||
available_bits/mod_order,
|
available_bits/mod_order,
|
||||||
tx_layers);
|
tx_layers);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < 2*available_bits/mod_order; i++)
|
||||||
|
tx_layers[0][i] = (tx_layers[0][i] * AMP) >> 15;
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////// ULSCH transform precoding ////////////////////////
|
||||||
|
///////////
|
||||||
|
|
||||||
|
l_prime[0] = 0; // single symbol ap 0
|
||||||
|
uint8_t dmrs_symbol = l0+l_prime[0], l; // Assuming dmrs-AdditionalPosition = 0
|
||||||
|
|
||||||
|
#ifdef NR_SC_FDMA
|
||||||
|
uint32_t nb_re_pusch, nb_re_dmrs_per_rb;
|
||||||
|
uint32_t y_offset = 0;
|
||||||
|
|
||||||
|
for (l = start_symbol; l < start_symbol + ulsch_ue->Nsymb_pusch; l++) {
|
||||||
|
|
||||||
|
if(l == dmrs_symbol)
|
||||||
|
nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; // [hna] ulsch_ue->nb_re_dmrs = 6 in this configuration
|
||||||
|
else
|
||||||
|
nb_re_dmrs_per_rb = 0;
|
||||||
|
|
||||||
|
nb_re_pusch = harq_process_ul_ue->nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb);
|
||||||
|
|
||||||
|
nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch);
|
||||||
|
|
||||||
|
y_offset = y_offset + nb_re_pusch;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////ULSCH RE mapping/////////////////////////
|
/////////////////////////ULSCH RE mapping/////////////////////////
|
||||||
///////////
|
///////////
|
||||||
|
|
||||||
@@ -387,10 +318,9 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
get_Wt(Wt, ap, dmrs_type);
|
get_Wt(Wt, ap, dmrs_type);
|
||||||
get_Wf(Wf, ap, dmrs_type);
|
get_Wf(Wf, ap, dmrs_type);
|
||||||
delta = get_delta(ap, dmrs_type);
|
delta = get_delta(ap, dmrs_type);
|
||||||
l_prime[0] = 0; // single symbol ap 0
|
|
||||||
uint8_t dmrs_symbol = l0+l_prime[0]; // Assuming dmrs-AdditionalPosition = 0
|
|
||||||
|
|
||||||
uint8_t k_prime=0, l;
|
uint8_t k_prime=0;
|
||||||
uint16_t m=0, n=0, dmrs_idx=0, k=0;
|
uint16_t m=0, n=0, dmrs_idx=0, k=0;
|
||||||
|
|
||||||
for (l=start_symbol; l<start_symbol+ulsch_ue->Nsymb_pusch; l++) {
|
for (l=start_symbol; l<start_symbol+ulsch_ue->Nsymb_pusch; l++) {
|
||||||
@@ -420,8 +350,8 @@ uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
||||||
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (AMP * tx_layers[ap][m<<1]) >> 15;
|
((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1];
|
||||||
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (AMP * tx_layers[ap][(m<<1) + 1]) >> 15;
|
((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1];
|
||||||
|
|
||||||
#ifdef DEBUG_PUSCH_MAPPING
|
#ifdef DEBUG_PUSCH_MAPPING
|
||||||
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
|
printf("m %d\t l %d \t k %d \t txdataF: %d %d\n",
|
||||||
|
|||||||
@@ -42,6 +42,11 @@
|
|||||||
#define nr_subframe_t lte_subframe_t
|
#define nr_subframe_t lte_subframe_t
|
||||||
#define nr_slot_t lte_subframe_t
|
#define nr_slot_t lte_subframe_t
|
||||||
|
|
||||||
|
// [hna] This enables SC-FDMA transmission in Uplink. If disabled, then OFDMA is used in UPLINK.
|
||||||
|
#ifndef NR_SC_FDMA
|
||||||
|
#define NR_SC_FDMA
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_NUM_SUBCARRIER_SPACING 5
|
#define MAX_NUM_SUBCARRIER_SPACING 5
|
||||||
|
|
||||||
#define NR_MAX_NB_RB 275
|
#define NR_MAX_NB_RB 275
|
||||||
|
|||||||
@@ -236,8 +236,8 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {
|
|||||||
uint8_t symbol;
|
uint8_t symbol;
|
||||||
|
|
||||||
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
|
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
|
||||||
nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
|
nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,11 +251,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, u
|
|||||||
|
|
||||||
for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) {
|
for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(symbol = symbol_start; symbol < symbol_end; symbol++) {
|
for(symbol = symbol_start; symbol < symbol_end; symbol++) {
|
||||||
|
|
||||||
nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid);
|
nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ int main(int argc, char **argv) {
|
|||||||
int ap;
|
int ap;
|
||||||
int tx_offset;
|
int tx_offset;
|
||||||
double txlev;
|
double txlev;
|
||||||
int start_rb = 90;
|
int start_rb = 30;
|
||||||
int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
|
int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user