mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 13:10:28 +00:00
Compare commits
10 Commits
multi_cc_s
...
issue-948-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cb59cf391 | ||
|
|
1afd63a998 | ||
|
|
55bfa2cee3 | ||
|
|
1b5dc509e3 | ||
|
|
47448f95ce | ||
|
|
7ff9d015e6 | ||
|
|
a901342138 | ||
|
|
d5e97ca6fe | ||
|
|
fe92feaecc | ||
|
|
ccf2d6f615 |
@@ -225,14 +225,16 @@
|
||||
<desc>nr_dlsim Test cases. (Test1: 106 PRBs 50 PDSCH-PRBs MCS Index 27),
|
||||
(Test2: 106 PRBs 50 PDSCH-PRBs MCS Index 16),
|
||||
(Test3: 106 MCS-TABLE 256 QAM MCS Index 26),
|
||||
(Test4: MCS 0, low SNR performance),
|
||||
(Test5: 4x4 MIMO, 1 Layer),
|
||||
(Test6: 4x4 MIMO, 2 Layers),
|
||||
(Test7: 4x4 MIMO, 4 Layers)</desc>
|
||||
(Test4: 106 MCS-TABLE 256 QAM MCS Index 22, Fading Channel),
|
||||
(Test5: MCS 0, low SNR performance),
|
||||
(Test6: 4x4 MIMO, 1 Layer),
|
||||
(Test7: 4x4 MIMO, 2 Layers),
|
||||
(Test8: 4x4 MIMO, 4 Layers)</desc>
|
||||
<main_exec>nr_dlsim</main_exec>
|
||||
<main_exec_args>-n100 -e27 -s30
|
||||
-n100 -e16 -s11 -S13
|
||||
-n100 -q1 -e26 -s30
|
||||
-n100 -q1 -e22 -s25 -gA
|
||||
-n100 -e0 -t95 -S-1.0 -i 2 1 0
|
||||
-n10 -s20 -U 3 0 0 2 -gA -x1 -y4 -z4
|
||||
-n10 -s20 -U 3 0 0 2 -gA -x2 -y4 -z4
|
||||
|
||||
@@ -225,6 +225,26 @@ static void nr_ulsch_channel_level(int size_est,
|
||||
|
||||
}
|
||||
|
||||
static inline void compensate_amplitude(const simde__m256i *h2, simde__m256i *rF, const int amp)
|
||||
{
|
||||
const simde__m128i *rF_128 = (const simde__m128i *)rF;
|
||||
const simde__m128i *h2_128 = (const simde__m128i *)h2;
|
||||
const simde__m256 ones = simde_mm256_set1_ps((float)amp);
|
||||
// sample 0, 1, 2, 3
|
||||
const simde__m256i o0 =
|
||||
simde_mm256_cvtps_epi32(simde_mm256_mul_ps(simde_mm256_div_ps(simde_mm256_cvtepi32_ps(simde_mm256_cvtepi16_epi32(rF_128[0])),
|
||||
simde_mm256_cvtepi32_ps(simde_mm256_cvtepi16_epi32(h2_128[0]))),
|
||||
ones));
|
||||
// sample 4, 5, 6, 7
|
||||
const simde__m256i o1 =
|
||||
simde_mm256_cvtps_epi32(simde_mm256_mul_ps(simde_mm256_div_ps(simde_mm256_cvtepi32_ps(simde_mm256_cvtepi16_epi32(rF_128[1])),
|
||||
simde_mm256_cvtepi32_ps(simde_mm256_cvtepi16_epi32(h2_128[1]))),
|
||||
ones));
|
||||
//*((simde__m256i *)rF) = simde_mm256_packs_epi32(o0, o1);
|
||||
*((simde__m128i *)rF) = simde_mm_packs_epi32(*((simde__m128i *)&o0), *(((simde__m128i *)&o0)+1));
|
||||
*(((simde__m128i *)rF)+1) = simde_mm_packs_epi32(*((simde__m128i *)&o1), *(((simde__m128i *)&o1)+1));
|
||||
}
|
||||
|
||||
static void nr_ulsch_channel_compensation(c16_t *rxFext,
|
||||
c16_t *chFext,
|
||||
c16_t *ul_ch_maga,
|
||||
@@ -236,6 +256,7 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext,
|
||||
nfapi_nr_pusch_pdu_t* rel15_ul,
|
||||
uint32_t symbol,
|
||||
uint32_t buffer_length,
|
||||
int32_t maxh_avg,
|
||||
uint32_t output_shift)
|
||||
{
|
||||
int mod_order = rel15_ul->qam_mod_order;
|
||||
@@ -247,19 +268,25 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext,
|
||||
simde__m256i QAM_ampc_256 = simde_mm256_setzero_si256();
|
||||
|
||||
if (mod_order == 4) {
|
||||
QAM_ampa_256 = simde_mm256_set1_epi16(QAM16_n1);
|
||||
const int16_t amp = (int16_t)((maxh_avg >> output_shift) * 2 / sqrt(10));
|
||||
QAM_ampa_256 = simde_mm256_set1_epi16(amp);
|
||||
QAM_ampb_256 = simde_mm256_setzero_si256();
|
||||
QAM_ampc_256 = simde_mm256_setzero_si256();
|
||||
}
|
||||
else if (mod_order == 6) {
|
||||
QAM_ampa_256 = simde_mm256_set1_epi16(QAM64_n1);
|
||||
QAM_ampb_256 = simde_mm256_set1_epi16(QAM64_n2);
|
||||
const int16_t amp = (int16_t)((maxh_avg >> output_shift) * 4 / sqrt(42));
|
||||
const int16_t ampb = (int16_t)((maxh_avg >> output_shift) * 2 / sqrt(42));
|
||||
QAM_ampa_256 = simde_mm256_set1_epi16(amp);
|
||||
QAM_ampb_256 = simde_mm256_set1_epi16(ampb);
|
||||
QAM_ampc_256 = simde_mm256_setzero_si256();
|
||||
}
|
||||
else if (mod_order == 8) {
|
||||
QAM_ampa_256 = simde_mm256_set1_epi16(QAM256_n1);
|
||||
QAM_ampb_256 = simde_mm256_set1_epi16(QAM256_n2);
|
||||
QAM_ampc_256 = simde_mm256_set1_epi16(QAM256_n3);
|
||||
const int16_t amp = (int16_t)((maxh_avg >> output_shift) * 8 / sqrt(170));
|
||||
const int16_t ampb = (int16_t)((maxh_avg >> output_shift) * 4 / sqrt(170));
|
||||
const int16_t ampc = (int16_t)((maxh_avg >> output_shift) * 2 / sqrt(170));
|
||||
QAM_ampa_256 = simde_mm256_set1_epi16(amp);
|
||||
QAM_ampb_256 = simde_mm256_set1_epi16(ampb);
|
||||
QAM_ampc_256 = simde_mm256_set1_epi16(ampc);
|
||||
}
|
||||
|
||||
for (int aatx = 0; aatx < nrOfLayers; aatx++) {
|
||||
@@ -277,19 +304,32 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext,
|
||||
simde__m256i comp = oai_mm256_cpx_mult_conj(chF_256[i], rxF_256[i], output_shift);
|
||||
rxComp_256[i] = simde_mm256_add_epi16(rxComp_256[i], comp);
|
||||
|
||||
simde__m256i h2 = simde_mm256_srai_epi32(simde_mm256_madd_epi16(chF_256[i], chF_256[i]), output_shift);
|
||||
h2 = simde_mm256_packs_epi32(h2, h2);
|
||||
// sum channel magnitude of all antenna (|h1|^2 + |h2|^2 + ...)
|
||||
h2 = simde_mm256_unpacklo_epi16(h2, h2);
|
||||
|
||||
const int amp = maxh_avg >> output_shift;
|
||||
compensate_amplitude(&h2, rxComp_256 + i, amp);
|
||||
|
||||
if (mod_order > 2) {
|
||||
simde__m256i mag = oai_mm256_smadd(chF_256[i], chF_256[i], output_shift); // |h|^2
|
||||
// pack and duplicate
|
||||
mag = simde_mm256_packs_epi32(mag, mag);
|
||||
mag = simde_mm256_unpacklo_epi16(mag, mag);
|
||||
|
||||
rxF_ch_maga_256[i] = simde_mm256_add_epi16(rxF_ch_maga_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampa_256));
|
||||
//rxF_ch_maga_256[i] = simde_mm256_add_epi16(rxF_ch_maga_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampa_256));
|
||||
rxF_ch_maga_256[i] = QAM_ampa_256;
|
||||
|
||||
if (mod_order > 4)
|
||||
rxF_ch_magb_256[i] = simde_mm256_add_epi16(rxF_ch_magb_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampb_256));
|
||||
if (mod_order > 4) {
|
||||
//rxF_ch_magb_256[i] = simde_mm256_add_epi16(rxF_ch_magb_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampb_256));
|
||||
rxF_ch_magb_256[i] = QAM_ampb_256;
|
||||
}
|
||||
|
||||
if (mod_order > 6)
|
||||
rxF_ch_magc_256[i] = simde_mm256_add_epi16(rxF_ch_magc_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampc_256));
|
||||
if (mod_order > 6) {
|
||||
//rxF_ch_magc_256[i] = simde_mm256_add_epi16(rxF_ch_magc_256[i], simde_mm256_mulhrs_epi16(mag, QAM_ampc_256));
|
||||
rxF_ch_magc_256[i] = QAM_ampc_256;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rho != NULL) {
|
||||
@@ -984,8 +1024,30 @@ static void inner_rx(PHY_VARS_gNB *gNB,
|
||||
rel15_ul,
|
||||
symbol,
|
||||
buffer_length,
|
||||
pusch_vars->maxh_avgs,
|
||||
output_shift);
|
||||
|
||||
#define DUMP_PUSCH_BUFF 1
|
||||
#if DUMP_PUSCH_BUFF
|
||||
const uint32_t numValidREs = dmrs_symbol_flag ? (rel15_ul->dmrs_config_type == NFAPI_NR_DMRS_TYPE1)
|
||||
? rel15_ul->rb_size * (12 - 6 * rel15_ul->num_dmrs_cdm_grps_no_data)
|
||||
: rel15_ul->rb_size * (12 - 4 * rel15_ul->num_dmrs_cdm_grps_no_data)
|
||||
: 12 * rel15_ul->rb_size;
|
||||
const int decimation = 1;
|
||||
const uint32_t format = 1 | MATLAB_RAW;
|
||||
for (int r = 0; r < nb_rx_ant; r++) {
|
||||
char fName[50];
|
||||
for (int l = 0; l < nb_layer; l++) {
|
||||
snprintf(fName, sizeof(fName), "chestF_ext_l%d_r%d_s%d.m", l, r, symbol);
|
||||
LOG_M(fName, "chest_ext", chFext[l][r], numValidREs, decimation, format);
|
||||
snprintf(fName, sizeof(fName), "rxF_comp_l%d_s%d.m", l, symbol);
|
||||
LOG_M(fName, "rxF_comp", pusch_vars->rxdataF_comp[l * nb_rx_ant] + symbol * buffer_length, numValidREs, decimation, format);
|
||||
}
|
||||
snprintf(fName, sizeof(fName), "rxF_ext_r%d_s%d.m", r, symbol);
|
||||
LOG_M(fName, "rxf_ext", rxFext[r], numValidREs, decimation, format);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nb_layer == 1 && rel15_ul->transform_precoding == transformPrecoder_enabled && rel15_ul->qam_mod_order <= 6) {
|
||||
if (rel15_ul->qam_mod_order > 2)
|
||||
nr_freq_equalization(frame_parms,
|
||||
@@ -1368,6 +1430,8 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++)
|
||||
avgs = cmax(avgs, avg[nl * frame_parms->nb_antennas_rx + aarx]);
|
||||
|
||||
pusch_vars->maxh_avgs = avgs;
|
||||
|
||||
if (rel15_ul->nrOfLayers == 2 && rel15_ul->qam_mod_order > 6)
|
||||
pusch_vars->log2_maxh = (log2_approx(avgs) >> 1) - 3; // for MMSE
|
||||
else if (rel15_ul->nrOfLayers == 2)
|
||||
|
||||
@@ -191,7 +191,8 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
|
||||
unsigned char mod_order,
|
||||
unsigned short nb_rb,
|
||||
unsigned char output_shift,
|
||||
PHY_NR_MEASUREMENTS *measurements);
|
||||
PHY_NR_MEASUREMENTS *measurements,
|
||||
int32_t ch_mag2_avg);
|
||||
|
||||
/** \brief This function computes the average channel level over all allocated RBs and antennas (TX/RX) in order to compute output shift for compensated signal
|
||||
@param dl_ch_estimates_ext Channel estimates in allocated RBs
|
||||
@@ -226,6 +227,34 @@ static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
|
||||
int32_t dl_ch_magr[][n_rx][rx_size_symbol],
|
||||
unsigned char symbol,
|
||||
int length);
|
||||
static void nr_dlsch_ch_mag(const uint32_t rx_size_symbol,
|
||||
const int nbRx,
|
||||
int32_t dl_ch_mag[][nbRx][rx_size_symbol],
|
||||
int32_t dl_ch_magb[][nbRx][rx_size_symbol],
|
||||
int32_t dl_ch_magr[][nbRx][rx_size_symbol],
|
||||
const unsigned char mod_order,
|
||||
const uint8_t n_layers,
|
||||
const int length,
|
||||
const unsigned char output_shift,
|
||||
const int32_t ch_mag2_avg);
|
||||
static void nr_dlsch_comp_mag(const uint32_t rx_size_symbol,
|
||||
const int nbRx,
|
||||
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
|
||||
const int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||
const uint8_t n_layers,
|
||||
const unsigned char symbol,
|
||||
const int length,
|
||||
const unsigned char output_shift,
|
||||
const int32_t ch_mag2_avg);
|
||||
static void nr_dlsch_compensate_channel_phase(const uint32_t rx_size_symbol,
|
||||
const c16_t rxdataF_ext[][rx_size_symbol],
|
||||
const int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||
const uint16_t n_rx,
|
||||
const uint16_t n_layers,
|
||||
const uint32_t length,
|
||||
const uint32_t symbol,
|
||||
const uint32_t output_shift,
|
||||
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT]);
|
||||
|
||||
static bool overlap_csi_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t *csi_pdu, int symbol)
|
||||
{
|
||||
@@ -312,11 +341,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
unsigned char harq_pid,
|
||||
uint32_t pdsch_est_size,
|
||||
int32_t dl_ch_estimates[][pdsch_est_size],
|
||||
int layer_llr_size,
|
||||
int16_t layer_llr[][layer_llr_size],
|
||||
int16_t *llr[2],
|
||||
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
uint32_t llr_offset[NR_SYMBOLS_PER_SLOT],
|
||||
int32_t *log2_maxh,
|
||||
int32_t *ch_avgs,
|
||||
int rx_size_symbol,
|
||||
int nbRx,
|
||||
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
|
||||
@@ -434,6 +465,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
//----------------------------------------------------------
|
||||
const int n_rx = frame_parms->nb_antennas_rx;
|
||||
const bool meas_enabled = cpumeas(CPUMEAS_GETSTATE);
|
||||
int log2_maxh = 0;
|
||||
|
||||
{
|
||||
start_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS);
|
||||
@@ -473,10 +505,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
ue->phy_cpu_stats.cpu_time_stats[DLSCH_EXTRACT_RBS_STATS].p_time / (cpuf * 1000.0));
|
||||
}
|
||||
if (ue->phy_sim_pdsch_rxdataF_ext)
|
||||
for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
int offset = ((void *)rxdataF_ext[aarx] - (void *)rxdataF_ext) + symbol * rx_size_symbol;
|
||||
memcpy(ue->phy_sim_pdsch_rxdataF_ext + offset, rxdataF_ext, rx_size_symbol * sizeof(c16_t));
|
||||
}
|
||||
memcpy(ue->phy_sim_pdsch_rxdataF_ext + symbol * sizeof(rxdataF_ext), rxdataF_ext, sizeof(rxdataF_ext));
|
||||
|
||||
nb_re_pdsch = (pilots == 1) ? ((config_type == NFAPI_NR_DMRS_TYPE1) ? nb_rb_pdsch * (12 - 6 * dlsch_config->n_dmrs_cdm_groups)
|
||||
: nb_rb_pdsch * (12 - 4 * dlsch_config->n_dmrs_cdm_groups))
|
||||
@@ -507,26 +536,25 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
nr_dlsch_channel_level(rx_size_symbol, dl_ch_estimates_ext, frame_parms->nb_antennas_rx, nl, avg, nb_re_pdsch);
|
||||
else
|
||||
LOG_E(NR_PHY, "Average channel level is 0: nb_rb_pdsch = %d, nb_re_pdsch = %d\n", nb_rb_pdsch, nb_re_pdsch);
|
||||
int avgs = 0;
|
||||
int32_t median[MAX_ANT][MAX_ANT];
|
||||
for (int aatx = 0; aatx < nl; aatx++)
|
||||
for (int aarx = 0; aarx < n_rx; aarx++) {
|
||||
avgs = cmax(avgs, avg[aatx][aarx]);
|
||||
*ch_avgs = cmax(*ch_avgs, avg[aatx][aarx]);
|
||||
LOG_D(PHY, "nb_rb %d avg_%d_%d Power per SC is %d\n", nb_rb_pdsch, aarx, aatx, avg[aatx][aarx]);
|
||||
LOG_D(PHY, "avgs Power per SC is %d\n", avgs);
|
||||
LOG_D(PHY, "avgs Power per SC is %d\n", *ch_avgs);
|
||||
median[aatx][aarx] = avg[aatx][aarx];
|
||||
}
|
||||
if (nl > 1) {
|
||||
nr_dlsch_channel_level_median(rx_size_symbol, dl_ch_estimates_ext, median, nl, n_rx, nb_re_pdsch);
|
||||
for (int aatx = 0; aatx < nl; aatx++) {
|
||||
for (int aarx = 0; aarx < n_rx; aarx++) {
|
||||
avgs = cmax(avgs, median[aatx][aarx]);
|
||||
*ch_avgs = cmax(*ch_avgs, median[aatx][aarx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
*log2_maxh = (log2_approx(avgs) / 2) + 1;
|
||||
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs);
|
||||
}
|
||||
log2_maxh = (log2_approx(*ch_avgs) / 2);
|
||||
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, log2_maxh, *ch_avgs);
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS);
|
||||
if (meas_enabled) {
|
||||
LOG_D(PHY,
|
||||
@@ -547,24 +575,15 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
//----------------------------------------------------------
|
||||
// Disable correlation measurement for optimizing UE
|
||||
start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS);
|
||||
nr_dlsch_channel_compensation(rx_size_symbol,
|
||||
nbRx,
|
||||
rxdataF_ext,
|
||||
dl_ch_estimates_ext,
|
||||
dl_ch_mag,
|
||||
dl_ch_magb,
|
||||
dl_ch_magr,
|
||||
rxdataF_comp,
|
||||
NULL,
|
||||
frame_parms,
|
||||
nl,
|
||||
symbol,
|
||||
nb_re_pdsch,
|
||||
first_symbol_flag,
|
||||
dlsch_config->qamModOrder,
|
||||
nb_rb_pdsch,
|
||||
*log2_maxh,
|
||||
measurements); // log2_maxh+I0_shift
|
||||
nr_dlsch_compensate_channel_phase(rx_size_symbol,
|
||||
rxdataF_ext,
|
||||
dl_ch_estimates_ext,
|
||||
nbRx,
|
||||
nl,
|
||||
nb_re_pdsch,
|
||||
symbol,
|
||||
log2_maxh,
|
||||
rxdataF_comp);
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_COMPENSATION_STATS);
|
||||
if (meas_enabled) {
|
||||
LOG_D(PHY,
|
||||
@@ -573,7 +592,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
nr_slot_rx,
|
||||
slot,
|
||||
symbol,
|
||||
*log2_maxh,
|
||||
log2_maxh,
|
||||
ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_COMPENSATION_STATS].p_time / (cpuf * 1000.0));
|
||||
}
|
||||
// Please keep it: useful for debugging
|
||||
@@ -609,22 +628,36 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
dl_ch_magr,
|
||||
symbol,
|
||||
nb_re_pdsch);
|
||||
if (nl >= 2) // Apply MMSE for 2, 3, and 4 Tx layers
|
||||
if (nb_re_pdsch)
|
||||
nr_dlsch_mmse(rx_size_symbol,
|
||||
n_rx,
|
||||
nl,
|
||||
rxdataF_comp,
|
||||
dl_ch_mag,
|
||||
dl_ch_magb,
|
||||
dl_ch_magr,
|
||||
dl_ch_estimates_ext,
|
||||
nb_rb_pdsch,
|
||||
dlsch_config->qamModOrder,
|
||||
*log2_maxh,
|
||||
symbol,
|
||||
nb_re_pdsch,
|
||||
nvar);
|
||||
}
|
||||
if (nl > 1) { // Apply MMSE for 2, 3, and 4 Tx layers
|
||||
AssertFatal(n_rx > 1, "Number of Rx antennas less than layers\n");
|
||||
if (nb_re_pdsch)
|
||||
nr_dlsch_mmse(rx_size_symbol,
|
||||
n_rx,
|
||||
nl,
|
||||
rxdataF_comp,
|
||||
dl_ch_mag,
|
||||
dl_ch_magb,
|
||||
dl_ch_magr,
|
||||
dl_ch_estimates_ext,
|
||||
nb_rb_pdsch,
|
||||
dlsch_config->qamModOrder,
|
||||
log2_maxh,
|
||||
symbol,
|
||||
nb_re_pdsch,
|
||||
nvar);
|
||||
} else {
|
||||
nr_dlsch_comp_mag(rx_size_symbol, n_rx, rxdataF_comp, dl_ch_estimates_ext, nl, symbol, nb_re_pdsch, log2_maxh, *ch_avgs);
|
||||
nr_dlsch_ch_mag(rx_size_symbol,
|
||||
n_rx,
|
||||
dl_ch_mag,
|
||||
dl_ch_magb,
|
||||
dl_ch_magr,
|
||||
dlsch_config->qamModOrder,
|
||||
nl,
|
||||
nb_re_pdsch,
|
||||
log2_maxh,
|
||||
*ch_avgs);
|
||||
}
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_MRC_MMSE_STATS);
|
||||
|
||||
@@ -671,47 +704,28 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
dlsch);
|
||||
dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol];
|
||||
}
|
||||
start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
|
||||
nr_dlsch_llr(rx_size_symbol,
|
||||
nbRx,
|
||||
layer_llr_size,
|
||||
layer_llr,
|
||||
rxdataF_comp,
|
||||
dl_ch_mag[0][0],
|
||||
dl_ch_magb[0][0],
|
||||
dl_ch_magr[0][0],
|
||||
dlsch0_harq,
|
||||
dlsch1_harq,
|
||||
symbol,
|
||||
dl_valid_re[symbol],
|
||||
dlsch,
|
||||
llr_offset[symbol]);
|
||||
if (symbol < startSymbIdx + nbSymb - 1) // up to the penultimate symbol
|
||||
llr_offset[symbol + 1] = dl_valid_re[symbol] * dlsch_config->qamModOrder + llr_offset[symbol];
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
|
||||
/* at last symbol in a slot calculate LLR's for whole slot */
|
||||
if(symbol == (startSymbIdx + nbSymb - 1)) {
|
||||
const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl;
|
||||
|
||||
if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) {
|
||||
LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size];
|
||||
for(int i = startSymbIdx; i < startSymbIdx + nbSymb; i++) {
|
||||
/* Calculate LLR's for each symbol */
|
||||
start_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
|
||||
nr_dlsch_llr(rx_size_symbol,
|
||||
nbRx,
|
||||
rx_llr_layer_size,
|
||||
layer_llr,
|
||||
rxdataF_comp,
|
||||
dl_ch_mag[0][0],
|
||||
dl_ch_magb[0][0],
|
||||
dl_ch_magr[0][0],
|
||||
dlsch0_harq,
|
||||
dlsch1_harq,
|
||||
i,
|
||||
dl_valid_re[i],
|
||||
dlsch,
|
||||
llr_offset[i]);
|
||||
if (i < startSymbIdx + nbSymb - 1) // up to the penultimate symbol
|
||||
llr_offset[i + 1] = dl_valid_re[i] * dlsch_config->qamModOrder + llr_offset[i];
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_LLR_STATS);
|
||||
}
|
||||
|
||||
if (symbol == (startSymbIdx + nbSymb - 1)) {
|
||||
start_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
|
||||
nr_dlsch_layer_demapping(llr,
|
||||
dlsch[0].Nl,
|
||||
dlsch_config->qamModOrder,
|
||||
G,
|
||||
codeword_TB0,
|
||||
codeword_TB1,
|
||||
rx_llr_layer_size,
|
||||
layer_llr);
|
||||
nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch_config->qamModOrder, G, codeword_TB0, codeword_TB1, layer_llr_size, layer_llr);
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_LAYER_DEMAPPING);
|
||||
/*
|
||||
for (int i=0; i < 2; i++){
|
||||
@@ -763,12 +777,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
|
||||
if (ue->phy_sim_pdsch_rxdataF_comp)
|
||||
for (int a = 0; a < nbRx; a++) {
|
||||
int offset = (void *)rxdataF_comp[0][a] - (void *)rxdataF_comp[0] + symbol * rx_size_symbol * sizeof(c16_t);
|
||||
memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset, rxdataF_comp[0][a] + symbol * rx_size_symbol, sizeof(c16_t) * rx_size_symbol);
|
||||
for (int l = 0; l < nl; l++) {
|
||||
int offset = (void *)rxdataF_comp[l][a] - (void *)rxdataF_comp[0] + symbol * rx_size_symbol * sizeof(c16_t);
|
||||
memcpy(ue->phy_sim_pdsch_rxdataF_comp + offset,
|
||||
rxdataF_comp[l][a] + symbol * rx_size_symbol,
|
||||
sizeof(c16_t) * rx_size_symbol);
|
||||
}
|
||||
memcpy((c16_t *)ue->phy_sim_pdsch_dl_ch_estimates + pdsch_est_size * a, dl_ch_estimates, pdsch_est_size * sizeof(c16_t));
|
||||
}
|
||||
if (ue->phy_sim_pdsch_dl_ch_estimates_ext)
|
||||
memcpy((c16_t *)ue->phy_sim_pdsch_dl_ch_estimates_ext + symbol * rx_size_symbol,
|
||||
memcpy(ue->phy_sim_pdsch_dl_ch_estimates_ext + symbol * sizeof(dl_ch_estimates_ext),
|
||||
dl_ch_estimates_ext,
|
||||
sizeof(dl_ch_estimates_ext));
|
||||
return (0);
|
||||
@@ -825,6 +843,172 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
|
||||
// Pre-processing for LLR computation
|
||||
//==============================================================================================
|
||||
|
||||
static inline void compensate_amplitude(const simde__m128i *h2, simde__m128i *rF, const int amp)
|
||||
{
|
||||
const simde__m128i rF_128 = *rF;
|
||||
const simde__m128i h2_128 = *h2;
|
||||
const simde__m128 ones = simde_mm_set1_ps((float)amp);
|
||||
// sample 0, 1
|
||||
const simde__m128i o0 = simde_mm_cvtps_epi32(simde_mm_mul_ps(
|
||||
simde_mm_div_ps(simde_mm_cvtepi32_ps(simde_mm_cvtepi16_epi32(rF_128)), simde_mm_cvtepi32_ps(simde_mm_cvtepi16_epi32(h2_128))),
|
||||
ones));
|
||||
// sample 2, 3
|
||||
const simde__m128i o1 = simde_mm_cvtps_epi32(
|
||||
simde_mm_mul_ps(simde_mm_div_ps(simde_mm_cvtepi32_ps(simde_mm_cvtepi16_epi32(simde_mm_shuffle_epi32(rF_128, 0b1110))),
|
||||
simde_mm_cvtepi32_ps(simde_mm_cvtepi16_epi32(simde_mm_shuffle_epi32(h2_128, 0b1110)))),
|
||||
ones));
|
||||
*((simde__m128i *)rF) = simde_mm_packs_epi32(o0, o1);
|
||||
}
|
||||
|
||||
static void nr_dlsch_ch_mag(const uint32_t rx_size_symbol,
|
||||
const int nbRx,
|
||||
int32_t dl_ch_mag[][nbRx][rx_size_symbol],
|
||||
int32_t dl_ch_magb[][nbRx][rx_size_symbol],
|
||||
int32_t dl_ch_magr[][nbRx][rx_size_symbol],
|
||||
const unsigned char mod_order,
|
||||
const uint8_t n_layers,
|
||||
const int length,
|
||||
const unsigned char output_shift,
|
||||
const int32_t ch_mag2_avg)
|
||||
{
|
||||
const uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0);
|
||||
|
||||
for (int l = 0; l < n_layers; l++) {
|
||||
simde__m128i QAM_amp128 = {0}, QAM_amp128b = {0}, QAM_amp128r = {0};
|
||||
if (mod_order == 4) {
|
||||
const int16_t amp = (int16_t)((ch_mag2_avg >> output_shift) * 2 / sqrt(10));
|
||||
QAM_amp128 = simde_mm_set1_epi16(amp); // 2/sqrt(10)
|
||||
QAM_amp128b = simde_mm_setzero_si128();
|
||||
QAM_amp128r = simde_mm_setzero_si128();
|
||||
} else if (mod_order == 6) {
|
||||
const int16_t amp = (int16_t)((ch_mag2_avg >> output_shift) * 4 / sqrt(42));
|
||||
const int16_t ampb = (int16_t)((ch_mag2_avg >> output_shift) * 2 / sqrt(42));
|
||||
QAM_amp128 = simde_mm_set1_epi16(amp);
|
||||
QAM_amp128b = simde_mm_set1_epi16(ampb);
|
||||
QAM_amp128r = simde_mm_setzero_si128();
|
||||
} else if (mod_order == 8) {
|
||||
const int16_t amp = (int16_t)((ch_mag2_avg >> output_shift) * 8 / sqrt(170));
|
||||
const int16_t ampb = (int16_t)((ch_mag2_avg >> output_shift) * 4 / sqrt(170));
|
||||
const int16_t ampr = (int16_t)((ch_mag2_avg >> output_shift) * 2 / sqrt(170));
|
||||
QAM_amp128 = simde_mm_set1_epi16(amp);
|
||||
QAM_amp128b = simde_mm_set1_epi16(ampb);
|
||||
QAM_amp128r = simde_mm_set1_epi16(ampr);
|
||||
}
|
||||
|
||||
for (int aarx = 0; aarx < nbRx; aarx++) {
|
||||
simde__m128i *dl_ch_mag128 = (simde__m128i *)dl_ch_mag[l][aarx];
|
||||
simde__m128i *dl_ch_mag128b = (simde__m128i *)dl_ch_magb[l][aarx];
|
||||
simde__m128i *dl_ch_mag128r = (simde__m128i *)dl_ch_magr[l][aarx];
|
||||
|
||||
for (int rb = 0; rb < nb_rb_0; rb++) {
|
||||
if (mod_order > 2) {
|
||||
// get channel amplitude if not QPSK
|
||||
|
||||
dl_ch_mag128[0] = QAM_amp128;
|
||||
dl_ch_mag128b[0] = QAM_amp128b;
|
||||
dl_ch_mag128r[0] = QAM_amp128r;
|
||||
|
||||
dl_ch_mag128[1] = dl_ch_mag128[2] = dl_ch_mag128[0];
|
||||
dl_ch_mag128b[1] = dl_ch_mag128b[2] = dl_ch_mag128b[0];
|
||||
dl_ch_mag128r[1] = dl_ch_mag128r[2] = dl_ch_mag128r[0];
|
||||
}
|
||||
|
||||
dl_ch_mag128 += 3;
|
||||
dl_ch_mag128b += 3;
|
||||
dl_ch_mag128r += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compesate for channel amplitude only in case of single layer
|
||||
*/
|
||||
static void nr_dlsch_comp_mag(const uint32_t rx_size_symbol,
|
||||
const int nbRx,
|
||||
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
|
||||
const int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||
const uint8_t n_layers,
|
||||
const unsigned char symbol,
|
||||
const int length,
|
||||
const unsigned char output_shift,
|
||||
const int32_t ch_mag2_avg)
|
||||
{
|
||||
const uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0);
|
||||
|
||||
/* we could also call MMSE directly here but I'm not sure if the complexity is justified given there is only one layer
|
||||
need to check the performance difference after rewritting MMSE funtion to handle one layer
|
||||
*/
|
||||
AssertFatal(n_layers == 1, "Call nr_dlsch_mmse() for more than 1 layer\n");
|
||||
for (int l = 0; l < n_layers; l++) {
|
||||
// holds sum of channel magnitude of all antennas for each RE
|
||||
c16_t h2[rx_size_symbol];
|
||||
memset(h2, 0, sizeof(h2));
|
||||
for (int_fast8_t aarx = 0; aarx < nbRx; aarx++) {
|
||||
simde__m128i *h2_128 = (simde__m128i *)h2;
|
||||
const simde__m128i *dl_ch128 = (const simde__m128i *)dl_ch_estimates_ext[(l * nbRx) + aarx];
|
||||
for (int rb = 0; rb < nb_rb_0; rb++) {
|
||||
simde__m128i h2_0 = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[0], dl_ch128[0]), output_shift);
|
||||
simde__m128i h2_1 = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[1], dl_ch128[1]), output_shift);
|
||||
simde__m128i h2_2 = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[2], dl_ch128[2]), output_shift);
|
||||
h2_0 = simde_mm_packs_epi32(h2_0, h2_1);
|
||||
// sum channel magnitude of all antenna (|h1|^2 + |h2|^2 + ...)
|
||||
h2_128[0] = simde_mm_add_epi16(h2_128[0], simde_mm_unpacklo_epi16(h2_0, h2_0));
|
||||
h2_128[1] = simde_mm_add_epi16(h2_128[1], simde_mm_unpackhi_epi16(h2_0, h2_0));
|
||||
h2_2 = simde_mm_packs_epi32(h2_2, h2_2);
|
||||
h2_128[2] = simde_mm_add_epi16(h2_128[2], simde_mm_unpacklo_epi16(h2_2, h2_2));
|
||||
|
||||
h2_128 += 3;
|
||||
dl_ch128 += 3;
|
||||
}
|
||||
}
|
||||
simde__m128i *rxdataF_comp128 = (simde__m128i *)(rxdataF_comp[l][0] + symbol * rx_size_symbol);
|
||||
simde__m128i *h2_128 = (simde__m128i *)h2;
|
||||
const int h2_avg = ch_mag2_avg >> output_shift;
|
||||
for (int rb = 0; rb < nb_rb_0; rb++) {
|
||||
/* When using int16_t arithmetic to compensate channel magnitude, there is a chance of overflow when channel amplitude
|
||||
response has large dynamic range. So we have to use either int32 or floating point arithmetic. We use floating point. */
|
||||
compensate_amplitude(h2_128, rxdataF_comp128, h2_avg);
|
||||
compensate_amplitude(h2_128 + 1, rxdataF_comp128 + 1, h2_avg);
|
||||
compensate_amplitude(h2_128 + 2, rxdataF_comp128 + 2, h2_avg);
|
||||
|
||||
h2_128 += 3;
|
||||
rxdataF_comp128 += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_dlsch_compensate_channel_phase(const uint32_t rx_size_symbol,
|
||||
const c16_t rxdataF_ext[][rx_size_symbol],
|
||||
const int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||
const uint16_t n_rx,
|
||||
const uint16_t n_layers,
|
||||
const uint32_t length,
|
||||
const uint32_t symbol,
|
||||
const uint32_t output_shift,
|
||||
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT])
|
||||
{
|
||||
const uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0);
|
||||
for (int_fast16_t l = 0; l < n_layers; l++) {
|
||||
for (int_fast16_t aarx = 0; aarx < n_rx; aarx++) {
|
||||
simde__m128i *dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[(l * n_rx) + aarx];
|
||||
simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx];
|
||||
simde__m128i *rxdataF_comp128 = (simde__m128i *)(rxdataF_comp[l][aarx] + symbol * rx_size_symbol);
|
||||
|
||||
for (int_fast32_t rb = 0; rb < nb_rb_0; rb++) {
|
||||
// Multiply received data by conjugated channel
|
||||
rxdataF_comp128[0] = oai_mm_cpx_mult_conj(dl_ch128[0], rxdataF128[0], output_shift);
|
||||
rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift);
|
||||
rxdataF_comp128[2] = oai_mm_cpx_mult_conj(dl_ch128[2], rxdataF128[2], output_shift);
|
||||
|
||||
dl_ch128 += 3;
|
||||
rxdataF128 += 3;
|
||||
rxdataF_comp128 += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
|
||||
int nbRx,
|
||||
c16_t rxdataF_ext[][rx_size_symbol],
|
||||
@@ -842,26 +1026,33 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
|
||||
unsigned char mod_order,
|
||||
unsigned short nb_rb,
|
||||
unsigned char output_shift,
|
||||
PHY_NR_MEASUREMENTS *measurements)
|
||||
PHY_NR_MEASUREMENTS *measurements,
|
||||
int32_t ch_mag2_avg)
|
||||
{
|
||||
simde__m128i *dl_ch128, *dl_ch128_2, *dl_ch_mag128, *dl_ch_mag128b, *dl_ch_mag128r, *rxdataF128, *rxdataF_comp128, *rho128;
|
||||
simde__m128i mmtmpD0, mmtmpD1, QAM_amp128 = {0}, QAM_amp128b = {0}, QAM_amp128r = {0};
|
||||
simde__m128i QAM_amp128 = {0}, QAM_amp128b = {0}, QAM_amp128r = {0};
|
||||
|
||||
uint32_t nb_rb_0 = length / 12 + ((length % 12) ? 1 : 0);
|
||||
|
||||
for (int l = 0; l < n_layers; l++) {
|
||||
if (mod_order == 4) {
|
||||
QAM_amp128 = simde_mm_set1_epi16(QAM16_n1); // 2/sqrt(10)
|
||||
const int16_t amp = (int16_t)((ch_mag2_avg >> output_shift) * 2 / sqrt(10));
|
||||
QAM_amp128 = simde_mm_set1_epi16(amp); // 2/sqrt(10)
|
||||
QAM_amp128b = simde_mm_setzero_si128();
|
||||
QAM_amp128r = simde_mm_setzero_si128();
|
||||
} else if (mod_order == 6) {
|
||||
QAM_amp128 = simde_mm_set1_epi16(QAM64_n1); //
|
||||
QAM_amp128b = simde_mm_set1_epi16(QAM64_n2);
|
||||
const int16_t amp = (int16_t)((ch_mag2_avg >> output_shift) * 4 / sqrt(42));
|
||||
const int16_t ampb = (int16_t)((ch_mag2_avg >> output_shift) * 2 / sqrt(42));
|
||||
QAM_amp128 = simde_mm_set1_epi16(amp);
|
||||
QAM_amp128b = simde_mm_set1_epi16(ampb);
|
||||
QAM_amp128r = simde_mm_setzero_si128();
|
||||
} else if (mod_order == 8) {
|
||||
QAM_amp128 = simde_mm_set1_epi16(QAM256_n1);
|
||||
QAM_amp128b = simde_mm_set1_epi16(QAM256_n2);
|
||||
QAM_amp128r = simde_mm_set1_epi16(QAM256_n3);
|
||||
const int16_t amp = (int16_t)((ch_mag2_avg >> output_shift) * 8 / sqrt(170));
|
||||
const int16_t ampb = (int16_t)((ch_mag2_avg >> output_shift) * 4 / sqrt(170));
|
||||
const int16_t ampr = (int16_t)((ch_mag2_avg >> output_shift) * 2 / sqrt(170));
|
||||
QAM_amp128 = simde_mm_set1_epi16(amp);
|
||||
QAM_amp128b = simde_mm_set1_epi16(ampb);
|
||||
QAM_amp128r = simde_mm_set1_epi16(ampr);
|
||||
}
|
||||
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
@@ -876,41 +1067,13 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
|
||||
if (mod_order > 2) {
|
||||
// get channel amplitude if not QPSK
|
||||
|
||||
mmtmpD0 = simde_mm_madd_epi16(dl_ch128[0], dl_ch128[0]);
|
||||
mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift);
|
||||
dl_ch_mag128[0] = QAM_amp128;
|
||||
dl_ch_mag128b[0] = QAM_amp128b;
|
||||
dl_ch_mag128r[0] = QAM_amp128r;
|
||||
|
||||
mmtmpD1 = simde_mm_madd_epi16(dl_ch128[1], dl_ch128[1]);
|
||||
mmtmpD1 = simde_mm_srai_epi32(mmtmpD1, output_shift);
|
||||
|
||||
mmtmpD0 = simde_mm_packs_epi32(mmtmpD0, mmtmpD1); //|H[0]|^2 |H[1]|^2 |H[2]|^2 |H[3]|^2 |H[4]|^2 |H[5]|^2 |H[6]|^2 |H[7]|^2
|
||||
|
||||
// store channel magnitude here in a new field of dlsch
|
||||
|
||||
dl_ch_mag128[0] = simde_mm_unpacklo_epi16(mmtmpD0, mmtmpD0);
|
||||
dl_ch_mag128b[0] = dl_ch_mag128[0];
|
||||
dl_ch_mag128r[0] = dl_ch_mag128[0];
|
||||
dl_ch_mag128[0] = simde_mm_mulhrs_epi16(dl_ch_mag128[0], QAM_amp128);
|
||||
dl_ch_mag128b[0] = simde_mm_mulhrs_epi16(dl_ch_mag128b[0], QAM_amp128b);
|
||||
dl_ch_mag128r[0] = simde_mm_mulhrs_epi16(dl_ch_mag128r[0], QAM_amp128r);
|
||||
|
||||
dl_ch_mag128[1] = simde_mm_unpackhi_epi16(mmtmpD0, mmtmpD0);
|
||||
dl_ch_mag128b[1] = dl_ch_mag128[1];
|
||||
dl_ch_mag128r[1] = dl_ch_mag128[1];
|
||||
dl_ch_mag128[1] = simde_mm_mulhrs_epi16(dl_ch_mag128[1], QAM_amp128);
|
||||
dl_ch_mag128b[1] = simde_mm_mulhrs_epi16(dl_ch_mag128b[1], QAM_amp128b);
|
||||
dl_ch_mag128r[1] = simde_mm_mulhrs_epi16(dl_ch_mag128r[1], QAM_amp128r);
|
||||
|
||||
mmtmpD0 = simde_mm_madd_epi16(dl_ch128[2], dl_ch128[2]);
|
||||
mmtmpD0 = simde_mm_srai_epi32(mmtmpD0, output_shift);
|
||||
mmtmpD1 = simde_mm_packs_epi32(mmtmpD0, mmtmpD0);
|
||||
|
||||
dl_ch_mag128[2] = simde_mm_unpacklo_epi16(mmtmpD1, mmtmpD1);
|
||||
dl_ch_mag128b[2] = dl_ch_mag128[2];
|
||||
dl_ch_mag128r[2] = dl_ch_mag128[2];
|
||||
|
||||
dl_ch_mag128[2] = simde_mm_mulhrs_epi16(dl_ch_mag128[2], QAM_amp128);
|
||||
dl_ch_mag128b[2] = simde_mm_mulhrs_epi16(dl_ch_mag128b[2], QAM_amp128b);
|
||||
dl_ch_mag128r[2] = simde_mm_mulhrs_epi16(dl_ch_mag128r[2], QAM_amp128r);
|
||||
dl_ch_mag128[1] = dl_ch_mag128[2] = dl_ch_mag128[0];
|
||||
dl_ch_mag128b[1] = dl_ch_mag128b[2] = dl_ch_mag128b[0];
|
||||
dl_ch_mag128r[1] = dl_ch_mag128r[2] = dl_ch_mag128r[0];
|
||||
}
|
||||
|
||||
// Multiply received data by conjugated channel
|
||||
@@ -918,6 +1081,26 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
|
||||
rxdataF_comp128[1] = oai_mm_cpx_mult_conj(dl_ch128[1], rxdataF128[1], output_shift);
|
||||
rxdataF_comp128[2] = oai_mm_cpx_mult_conj(dl_ch128[2], rxdataF128[2], output_shift);
|
||||
|
||||
// Compensate channel amplitude
|
||||
simde__m128i h2_0 = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[0], dl_ch128[0]), output_shift);
|
||||
simde__m128i h2_1 = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[1], dl_ch128[1]), output_shift);
|
||||
simde__m128i h2_2 = simde_mm_srai_epi32(simde_mm_madd_epi16(dl_ch128[2], dl_ch128[2]), output_shift);
|
||||
h2_0 = simde_mm_packs_epi32(h2_0, h2_1);
|
||||
h2_0 = simde_mm_unpacklo_epi16(h2_0, h2_0);
|
||||
h2_1 = simde_mm_unpackhi_epi16(h2_0, h2_0);
|
||||
h2_2 = simde_mm_packs_epi32(h2_2, h2_2);
|
||||
h2_2 = simde_mm_unpacklo_epi16(h2_2, h2_2);
|
||||
/* When using int16_t arithmetic to compensate channel magnitude, there is a chance of overflow when channel amplitude
|
||||
response has large dynamic range. So we have to use either int32 or floating point arithmetic. We use floating point. */
|
||||
const int h2_avg = ch_mag2_avg >> output_shift;
|
||||
compensate_amplitude(&h2_0, rxdataF_comp128, h2_avg);
|
||||
compensate_amplitude(&h2_1, rxdataF_comp128 + 1, h2_avg);
|
||||
compensate_amplitude(&h2_2, rxdataF_comp128 + 2, h2_avg);
|
||||
|
||||
print_shorts(" Rx signal:=", (int16_t *)rxdataF_comp128);
|
||||
print_shorts(" Rx signal:=", (int16_t *)(rxdataF_comp128 + 1));
|
||||
print_shorts(" Rx signal:=", (int16_t *)(rxdataF_comp128 + 2));
|
||||
|
||||
dl_ch128 += 3;
|
||||
dl_ch_mag128 += 3;
|
||||
dl_ch_mag128b += 3;
|
||||
@@ -1510,6 +1693,62 @@ void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned sh
|
||||
mult_cpx_conj_vector(ch0, ch1, ch0conj_ch1, 12 * nb_rb, output_shift0);
|
||||
}
|
||||
|
||||
static void nr_matrix_scale_determin(const int size,
|
||||
const int length,
|
||||
const int nb_rb_0,
|
||||
const int shift,
|
||||
const c16_t determin[NR_NB_SC_PER_RB*nb_rb_0],
|
||||
c16_t *matrix[size][size])
|
||||
{
|
||||
/*
|
||||
Dividing two complex numbers:
|
||||
|
||||
a + bi (a + bi)(c - di)
|
||||
------ = ----------------
|
||||
c + di (c + di)(c - di)
|
||||
|
||||
ac + bd bc - ad
|
||||
= --------- + ----------- i
|
||||
c^2 + d^2 c^2 + d^2
|
||||
*/
|
||||
|
||||
// average of determin
|
||||
const int16_t x = factor2(length);
|
||||
const int16_t y = (length) >> x;
|
||||
simde__m128i *cd = (simde__m128i *)determin;
|
||||
const int32_t det_avg = simde_mm_average(cd, NR_NB_SC_PER_RB * nb_rb_0, x, y);
|
||||
const int32_t log2_det_avg = log2_approx(det_avg) / 2;
|
||||
for (int_fast16_t r = 0; r < size; r++) {
|
||||
for (int_fast16_t c = 0; c < size; c++) {
|
||||
// (a + bi)(c - di)
|
||||
mult_cpx_conj_vector(determin, matrix[r][c], matrix[r][c], NR_NB_SC_PER_RB * nb_rb_0, log2_det_avg);
|
||||
// scale by 1/(c^2 + d^2)
|
||||
simde__m128i *ab = (simde__m128i *)matrix[r][c];
|
||||
cd = (simde__m128i *)determin;
|
||||
for (int_fast16_t rb = 0; rb < nb_rb_0; rb++) {
|
||||
simde__m128i c2d2_unpack[3];
|
||||
c2d2_unpack[0] = simde_mm_srai_epi32(simde_mm_madd_epi16(cd[0], cd[0]), log2_det_avg);
|
||||
c2d2_unpack[1] = simde_mm_srai_epi32(simde_mm_madd_epi16(cd[1], cd[1]), log2_det_avg);
|
||||
c2d2_unpack[2] = simde_mm_srai_epi32(simde_mm_madd_epi16(cd[2], cd[2]), log2_det_avg);
|
||||
simde__m128i c2d2[3];
|
||||
const simde__m128i c2d2_01 = simde_mm_packs_epi32(c2d2_unpack[0], c2d2_unpack[1]);
|
||||
c2d2[0] = simde_mm_unpacklo_epi16(c2d2_01, c2d2_01);
|
||||
c2d2[1] = simde_mm_unpackhi_epi16(c2d2_01, c2d2_01);
|
||||
const simde__m128i c2d2_2 = simde_mm_packs_epi32(c2d2_unpack[2], c2d2_unpack[2]);
|
||||
c2d2[2] = simde_mm_unpacklo_epi16(c2d2_2, c2d2_2);
|
||||
|
||||
const int32_t c2d2_avg = 1 << shift;
|
||||
compensate_amplitude(c2d2, ab, c2d2_avg);
|
||||
compensate_amplitude(c2d2 + 1, ab + 1, c2d2_avg);
|
||||
compensate_amplitude(c2d2 + 2, ab + 2, c2d2_avg);
|
||||
|
||||
cd += 3;
|
||||
ab += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MMSE Rx function: up to 4 layers
|
||||
*/
|
||||
@@ -1587,6 +1826,9 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
|
||||
fp_flag, // fixed point flag
|
||||
shift - (fp_flag == 1 ? 2 : 0)); // the out put is Q15
|
||||
|
||||
// scale inv(H*H) by determinant
|
||||
nr_matrix_scale_determin(nl, length, nb_rb_0, shift /*- (fp_flag == 1 ? 2 : 0)*/, determ_fin, inv_H_h_H);
|
||||
|
||||
// multiply Matrix inversion pf H_h_H by the rx signal vector
|
||||
c16_t outtemp[12 * nb_rb_0] __attribute__((aligned(32)));
|
||||
//Allocate rxdataF for zforcing out
|
||||
|
||||
@@ -302,6 +302,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
unsigned char harq_pid,
|
||||
uint32_t pdsch_est_size,
|
||||
int32_t dl_ch_estimates[][pdsch_est_size],
|
||||
int layer_llr_size,
|
||||
int16_t layer_llr[][layer_llr_size],
|
||||
int16_t *llr[2],
|
||||
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
|
||||
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
|
||||
@@ -305,6 +305,8 @@ typedef struct {
|
||||
int32_t **rxdataF_comp;
|
||||
/// \f$\log_2(\max|H_i|^2)\f$
|
||||
int16_t log2_maxh;
|
||||
/// max|H_i|^2
|
||||
int32_t maxh_avgs;
|
||||
/// measured RX power based on DRS
|
||||
uint32_t ulsch_power[8];
|
||||
/// total signal over antennas
|
||||
|
||||
@@ -601,7 +601,15 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
uint32_t llr_offset[NR_SYMBOLS_PER_SLOT] = {0};
|
||||
|
||||
int32_t log2_maxh = 0;
|
||||
const uint32_t rx_llr_layer_size = (G + dlsch[0].Nl - 1) / dlsch[0].Nl;
|
||||
|
||||
if (dlsch[0].Nl == 0 || rx_llr_layer_size == 0 || rx_llr_layer_size > 10 * 1000 * 1000) {
|
||||
LOG_E(PHY, "rx_llr_layer_size %d, G %d, Nl, %d, discarding this pdsch\n", rx_llr_layer_size, G, dlsch[0].Nl);
|
||||
return -1;
|
||||
}
|
||||
__attribute__((aligned(32))) int16_t layer_llr[dlsch[0].Nl][rx_llr_layer_size];
|
||||
|
||||
int32_t ch_avgs = 0;
|
||||
start_meas_nr_ue_phy(ue, RX_PDSCH_STATS);
|
||||
for (int m = dlschCfg->start_symbol; m < (dlschCfg->number_symbols + dlschCfg->start_symbol); m++) {
|
||||
bool first_symbol_flag = false;
|
||||
@@ -618,11 +626,13 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
harq_pid,
|
||||
pdsch_est_size,
|
||||
pdsch_dl_ch_estimates,
|
||||
rx_llr_layer_size,
|
||||
layer_llr,
|
||||
llr,
|
||||
dl_valid_re,
|
||||
rxdataF,
|
||||
llr_offset,
|
||||
&log2_maxh,
|
||||
&ch_avgs,
|
||||
rx_size_symbol,
|
||||
ue->frame_parms.nb_antennas_rx,
|
||||
rxdataF_comp,
|
||||
@@ -1008,6 +1018,8 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
|
||||
phy_pdcch_config->nb_search_space = 0;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
|
||||
TracyCZoneEnd(ctx);
|
||||
if (ue->phy_sim_rxdataF)
|
||||
memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * nb_symb_pdcch * ue->frame_parms.ofdm_symbol_size);
|
||||
return sampleShift;
|
||||
}
|
||||
|
||||
@@ -1132,9 +1144,11 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
}
|
||||
|
||||
if (ue->phy_sim_rxdataF)
|
||||
memcpy(ue->phy_sim_rxdataF, rxdataF, sizeof(int32_t)*rxdataF_sz*ue->frame_parms.nb_antennas_rx);
|
||||
memcpy(ue->phy_sim_rxdataF + start_symb_sch * ue->frame_parms.ofdm_symbol_size * sizeof(c16_t),
|
||||
&rxdataF[0][start_symb_sch * ue->frame_parms.ofdm_symbol_size],
|
||||
sizeof(int32_t) * nb_symb_sch * ue->frame_parms.ofdm_symbol_size);
|
||||
if (ue->phy_sim_pdsch_llr)
|
||||
memcpy(ue->phy_sim_pdsch_llr, llr[0], sizeof(int16_t)*rx_llr_buf_sz);
|
||||
memcpy(ue->phy_sim_pdsch_llr, llr[0], sizeof(int16_t) * rx_llr_buf_sz);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
|
||||
for (int i=0; i<nb_codewords; i++)
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "NR_DL-CCCH-Message.h"
|
||||
#include "NR_BWP-Downlink.h"
|
||||
#include "NR_CellGroupConfig.h"
|
||||
#include "NR_MAC_COMMON/nr_mac.h"
|
||||
@@ -90,6 +91,7 @@
|
||||
#include "utils.h"
|
||||
#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
|
||||
#include "SIMULATION/LTE_PHY/common_sim.h"
|
||||
#include "openair2/COMMON/mac_messages_types.h"
|
||||
|
||||
const char *__asan_default_options()
|
||||
{
|
||||
@@ -295,6 +297,70 @@ void validate_input_pmi(nfapi_nr_config_request_scf_t *gNB_config,
|
||||
num_antenna_ports, pmi_pdu->num_ant_ports, pmi);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint64_t dl_freq;
|
||||
uint64_t frame;
|
||||
uint64_t slot;
|
||||
uint64_t cellid;
|
||||
uint64_t rnti;
|
||||
} param_from_file_t;
|
||||
|
||||
void load_sib1_config(const uint8_t *sdu, const uint32_t sdu_size, NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||
&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||
(void **)&bcch_message,
|
||||
(const void *)sdu,
|
||||
sdu_size);
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
printf("Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", dec_rval.consumed);
|
||||
// free the memory
|
||||
SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message);
|
||||
|
||||
NR_SIB1_t *sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
|
||||
NR_ServingCellConfigCommonSIB_t *scc = sib1->servingCellConfigCommon;
|
||||
int bwp_id = 0;
|
||||
config_common_ue_sa(mac, scc, 0);
|
||||
configure_common_BWP_dl(mac, bwp_id, &scc->downlinkConfigCommon.initialDownlinkBWP);
|
||||
}
|
||||
|
||||
void load_rrcsetup_config(const uint8_t *sdu, const uint32_t sdu_size, NR_UE_NR_Capability_t *ue_cap, NR_UE_MAC_INST_t *mac)
|
||||
{
|
||||
NR_DL_CCCH_Message_t *dl_ccch_msg = NULL;
|
||||
asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_CCCH_Message, (void **)&dl_ccch_msg, sdu, sdu_size, 0, 0);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)dl_ccch_msg);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
printf("Failed to decode DL-CCCH-Message (%zu bytes)\n", dec_rval.consumed);
|
||||
return;
|
||||
}
|
||||
if (dl_ccch_msg->message.present != NR_DL_CCCH_MessageType_PR_c1) {
|
||||
printf("No message present %d\n", dl_ccch_msg->message.present);
|
||||
return;
|
||||
} else {
|
||||
if (dl_ccch_msg->message.choice.c1->present != NR_DL_CCCH_MessageType__c1_PR_rrcSetup) {
|
||||
printf("Expected rrcSetup but got %d\n", dl_ccch_msg->message.choice.c1->present);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NR_RRCSetup_t *rrcSetup = dl_ccch_msg->message.choice.c1->choice.rrcSetup;
|
||||
OCTET_STRING_t *mcg = &rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup;
|
||||
NR_CellGroupConfig_t *cellGroupConfig = NULL;
|
||||
uper_decode(NULL,
|
||||
&asn_DEF_NR_CellGroupConfig, //might be added prefix later
|
||||
(void **)&cellGroupConfig,
|
||||
(uint8_t *)mcg->buf,
|
||||
mcg->size, 0, 0);
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
nr_rrc_mac_config_req_cg(0, 0, cellGroupConfig, ue_cap);
|
||||
}
|
||||
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char **argv)
|
||||
@@ -392,7 +458,7 @@ int main(int argc, char **argv)
|
||||
|
||||
FILE *scg_fd=NULL;
|
||||
|
||||
while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:wT:U:q:X:Y:Z:")) != -1) {
|
||||
|
||||
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
|
||||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||||
@@ -657,6 +723,26 @@ printf("%d\n", slot);
|
||||
get_softmodem_params()->do_ra = 0;
|
||||
IS_SOFTMODEM_DLSIM = true;
|
||||
|
||||
NRRrcMacCcchDataInd has_sib1;
|
||||
NRRrcMacCcchDataInd has_rrcSetup;
|
||||
param_from_file_t in_params = {0};
|
||||
uint64_t input_sample_size = 0;
|
||||
c16_t *input_slot_iq = NULL;
|
||||
if (input_fd) {
|
||||
int err = 0;
|
||||
err += fread(&in_params, sizeof(in_params), 1, input_fd);
|
||||
err += fread(&has_sib1.sdu_size, sizeof(has_sib1.sdu_size), 1, input_fd);
|
||||
err += fread(&has_sib1.sdu, has_sib1.sdu_size, 1, input_fd);
|
||||
err += fread(&has_rrcSetup.sdu_size, sizeof(has_rrcSetup.sdu_size), 1, input_fd);
|
||||
err += fread(&has_rrcSetup.sdu, has_rrcSetup.sdu_size, 1, input_fd);
|
||||
err += fread(&input_sample_size, sizeof(input_sample_size), 1, input_fd);
|
||||
printf("input sample size %ld\n",input_sample_size);
|
||||
input_slot_iq = malloc16_clear(sizeof(*input_slot_iq) * input_sample_size);
|
||||
err += fread(input_slot_iq, sizeof(c16_t), input_sample_size, input_fd);
|
||||
if (err == 0)
|
||||
printf("Error reading from file\n");
|
||||
}
|
||||
|
||||
if (snr1set==0)
|
||||
snr1 = snr0+10;
|
||||
|
||||
@@ -920,15 +1006,16 @@ printf("%d\n", slot);
|
||||
initFloatingCoresTpool(dlsch_threads, &nrUE_params.Tpool, false, "UE-tpool");
|
||||
|
||||
// generate signal
|
||||
AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
|
||||
|
||||
// clone CellGroup to have a separate copy at UE
|
||||
NR_CellGroupConfig_t *UE_CellGroup = clone_CellGroupConfig(secondaryCellGroup);
|
||||
|
||||
//Configure UE
|
||||
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
||||
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
||||
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup, UE_Capability_nr);
|
||||
if (input_fd == NULL) {
|
||||
nr_rrc_mac_config_req_mib(0, 0, mib->message.choice.mib, false);
|
||||
nr_rrc_mac_config_req_cg(0, 0, UE_CellGroup, UE_Capability_nr);
|
||||
}
|
||||
|
||||
asn1cFreeStruc(asn_DEF_NR_CellGroupConfig, UE_CellGroup);
|
||||
|
||||
@@ -1027,7 +1114,7 @@ printf("%d\n", slot);
|
||||
//n_errors2 = 0;
|
||||
//n_alamouti = 0;
|
||||
n_false_positive = 0;
|
||||
if (n_trials== 1) num_rounds = 1;
|
||||
if (input_fd != NULL || n_trials== 1) num_rounds = 1;
|
||||
|
||||
NR_gNB_DLSCH_t *gNB_dlsch = &msgDataTx->dlsch[0][0];
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15;
|
||||
@@ -1192,11 +1279,31 @@ printf("%d\n", slot);
|
||||
pdu_bit_map,
|
||||
0x1,
|
||||
UE->frame_parms.nb_antennas_rx);
|
||||
dl_config.sfn = frame;
|
||||
dl_config.slot = slot;
|
||||
ue_dci_configuration(UE_mac, &dl_config, frame, slot);
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
|
||||
if (input_fd) {
|
||||
UE_proc.frame_rx = frame = in_params.frame;
|
||||
UE_proc.nr_slot_rx = slot = in_params.slot;
|
||||
UE->frame_parms.Nid_cell = in_params.cellid;
|
||||
UE->frame_parms.dl_CarrierFreq = in_params.dl_freq;
|
||||
UE_mac->crnti = in_params.rnti;
|
||||
load_sib1_config(has_sib1.sdu, has_sib1.sdu_size, UE_mac);
|
||||
load_rrcsetup_config(has_rrcSetup.sdu, has_rrcSetup.sdu_size, UE_Capability_nr, UE_mac);
|
||||
nr_ue_phy_config_request(&UE_mac->phy_config);
|
||||
init_symbol_rotation(&UE->frame_parms);
|
||||
dl_config.sfn = frame;
|
||||
dl_config.slot = slot;
|
||||
ue_dci_configuration(UE_mac, &dl_config, frame, slot);
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
|
||||
slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
|
||||
memcpy(&UE->common_vars.rxdata[0][slot_offset], input_slot_iq, sizeof(c16_t) * slot_length);
|
||||
} else {
|
||||
dl_config.sfn = frame;
|
||||
dl_config.slot = slot;
|
||||
ue_dci_configuration(UE_mac, &dl_config, frame, slot);
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
}
|
||||
pbch_pdcch_processing(UE,
|
||||
&UE_proc,
|
||||
&phy_data);
|
||||
@@ -1213,11 +1320,11 @@ printf("%d\n", slot);
|
||||
int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr;
|
||||
|
||||
TBS = dlsch0->dlsch_config.TBS;//rel15->TBSize[0];
|
||||
uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
|
||||
uint16_t nb_rb = rel15->rbSize;
|
||||
uint8_t nb_re_dmrs = rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*dlsch0->dlsch_config.n_dmrs_cdm_groups : 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
|
||||
uint8_t mod_order = rel15->qamModOrder[0];
|
||||
uint8_t nb_symb_sch = rel15->NrOfSymbols;
|
||||
uint16_t length_dmrs = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos);
|
||||
uint16_t nb_rb = dlsch0->dlsch_config.number_rbs;
|
||||
uint8_t nb_re_dmrs = dlsch0->dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6*dlsch0->dlsch_config.n_dmrs_cdm_groups : 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
|
||||
uint8_t mod_order = dlsch0->dlsch_config.qamModOrder;
|
||||
uint8_t nb_symb_sch = dlsch0->dlsch_config.number_symbols;
|
||||
uint32_t unav_res = ptrsSymbPerSlot * ptrsRePerSymb;
|
||||
available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, unav_res, mod_order, rel15->nrOfLayers);
|
||||
if (pdu_bit_map & 0x1) {
|
||||
@@ -1342,23 +1449,38 @@ printf("%d\n", slot);
|
||||
if (UE->frame_parms.nb_antennas_rx>1)
|
||||
LOG_M("rxsig1.m", "rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, dec, op_format);
|
||||
LOG_M("rxF0.m", "rxF0", UE->phy_sim_rxdataF, frame_parms->samples_per_slot_wCP, dec, op_format);
|
||||
LOG_M("rxF_ext.m", "rxFe", UE->phy_sim_pdsch_rxdataF_ext, g_rbSize * 12 * 14, dec, op_format);
|
||||
const uint32_t numReSym = (g_rbSize * 12 + 15) & (~15);
|
||||
const uint32_t numValidReSym = g_rbSize * 12;
|
||||
{
|
||||
const int s = rel15->StartSymbolIndex;
|
||||
const int n = rel15->NrOfSymbols;
|
||||
for (int i = s; i < s + n; i++) {
|
||||
char fName[50];
|
||||
snprintf(fName, sizeof(fName), "chestF0_ext_s%d.m", i);
|
||||
LOG_M(fName,
|
||||
"chF0_ext",
|
||||
((c16_t *)UE->phy_sim_pdsch_dl_ch_estimates_ext) + (i * numReSym),
|
||||
numValidReSym,
|
||||
dec,
|
||||
op_format);
|
||||
snprintf(fName, sizeof(fName), "rxF_comp_s%d.m", i);
|
||||
LOG_M(fName, "rxFc", ((c16_t *)UE->phy_sim_pdsch_rxdataF_comp) + (i * numReSym), numValidReSym, dec, op_format);
|
||||
for (int l = 0; l < g_nrOfLayers; l++) {
|
||||
for (int r = 0; r < n_rx; r++) {
|
||||
const int s = rel15->StartSymbolIndex;
|
||||
const int n = rel15->NrOfSymbols;
|
||||
for (int i = s; i < s + n; i++) {
|
||||
const uint32_t dmrsBitMap = phy_data.dlsch[0].dlsch_config.dlDmrsSymbPos;
|
||||
const uint32_t dmrsCfg = phy_data.dlsch[0].dlsch_config.dmrsConfigType;
|
||||
const uint32_t nrb = phy_data.dlsch[0].dlsch_config.number_rbs;
|
||||
const uint32_t ncdmg = phy_data.dlsch[0].dlsch_config.n_dmrs_cdm_groups;
|
||||
const uint32_t numValidReSym = ((dmrsBitMap >> i) & 1)
|
||||
? ((dmrsCfg == NFAPI_NR_DMRS_TYPE1) ? nrb * (12 - 6 * ncdmg) : nrb * (12 - 4 * ncdmg))
|
||||
: (nrb * 12);
|
||||
char fName[50];
|
||||
snprintf(fName, sizeof(fName), "chestF_ext_l%d_r%d_s%d.m", l, r, i);
|
||||
uint32_t buff_offset = (i * g_nrOfLayers * n_rx * numReSym) + (l * n_rx * numReSym) + (r * numReSym);
|
||||
LOG_M(fName,
|
||||
"chF0_ext",
|
||||
((c16_t *)UE->phy_sim_pdsch_dl_ch_estimates_ext) + buff_offset,
|
||||
numValidReSym,
|
||||
dec,
|
||||
op_format);
|
||||
snprintf(fName, sizeof(fName), "rxF_comp_l%d_s%d.m", l, i);
|
||||
LOG_M(fName, "rxFc", ((c16_t *)UE->phy_sim_pdsch_rxdataF_comp) + (l * NR_SYMBOLS_PER_SLOT * numReSym) + (i * numReSym), numValidReSym, dec, op_format);
|
||||
if (l == 0) {
|
||||
snprintf(fName, sizeof(fName), "rxF_ext_r%d_s%d.m", r, i);
|
||||
buff_offset = (i * n_rx * numReSym) + (r * numReSym);
|
||||
LOG_M(fName, "rxFext", ((c16_t *)UE->phy_sim_pdsch_rxdataF_ext) + buff_offset, numValidReSym, dec, op_format);
|
||||
}
|
||||
snprintf(fName, sizeof(fName), "chestF0_s%d.m", i);
|
||||
LOG_M(fName, "chF0", ((c16_t *)UE->phy_sim_pdsch_dl_ch_estimates) + i * frame_parms->ofdm_symbol_size, nrb*12, dec, op_format);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_M("chestF0.m", "chF0", UE->phy_sim_pdsch_dl_ch_estimates, frame_parms->ofdm_symbol_size * 14, dec, op_format);
|
||||
@@ -1403,6 +1525,7 @@ printf("%d\n", slot);
|
||||
free(UE->phy_sim_pdsch_dl_ch_estimates);
|
||||
free(UE->phy_sim_pdsch_dl_ch_estimates_ext);
|
||||
free(UE->phy_sim_dlsch_b);
|
||||
free_and_zero(input_slot_iq);
|
||||
|
||||
free_nrLDPC_coding_interface(&gNB->nrLDPC_coding_interface);
|
||||
|
||||
|
||||
@@ -1384,7 +1384,7 @@ int main(int argc, char *argv[])
|
||||
1 | log_format);
|
||||
}
|
||||
|
||||
LOG_M("rxsigF0_llr.m",
|
||||
LOG_M("rxF_llr.m",
|
||||
"rxsF0_llr",
|
||||
&pusch_vars->llr[0],
|
||||
precod_nbr_layers * (nb_symb_sch - 1) * NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,
|
||||
|
||||
@@ -126,7 +126,7 @@ static void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, const frame_str
|
||||
}
|
||||
}
|
||||
|
||||
static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommonSIB_t *scc, int cc_idP)
|
||||
void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommonSIB_t *scc, int cc_idP)
|
||||
{
|
||||
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
||||
mac->phy_config.Mod_id = mac->ue_id;
|
||||
@@ -1553,7 +1553,7 @@ static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP
|
||||
}
|
||||
}
|
||||
|
||||
static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkCommon_t *dl_common)
|
||||
void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkCommon_t *dl_common)
|
||||
{
|
||||
if (dl_common) {
|
||||
NR_UE_DL_BWP_t *bwp = get_dl_bwp_structure(mac, bwp_id, true);
|
||||
|
||||
@@ -409,4 +409,6 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t
|
||||
|
||||
NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id);
|
||||
|
||||
void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkCommon_t *dl_common);
|
||||
void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommonSIB_t *scc, int cc_idP);
|
||||
#endif
|
||||
|
||||
117
tools/plots/dlsim_ext_data.py
Normal file
117
tools/plots/dlsim_ext_data.py
Normal file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# In[42]:
|
||||
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import struct
|
||||
import pandas as pd
|
||||
|
||||
|
||||
# In[109]:
|
||||
|
||||
|
||||
dataPath = '/home/sakthi/work/dlsim_perf/'
|
||||
#csv_filename = 'iq_14_6_ueTimeDomainSamples_mcs26' + '.csv'
|
||||
csv_filename = 'iq_197_6_ueTimeDomainSamples_mcs26_powerDrop1dB' + '.csv'
|
||||
df = pd.read_csv(dataPath + csv_filename, sep=';')
|
||||
dataR = df['real'].to_numpy().astype(np.int16)
|
||||
dataI = df['imag'].to_numpy().astype(np.int16)
|
||||
#shift = 2200
|
||||
#dataR = np.roll(dataR, shift)
|
||||
#dataI = np.roll(dataI, shift)
|
||||
plt.plot(dataR)
|
||||
print(dataI)
|
||||
dataInter = np.zeros((2*dataR.size),dtype=np.int16)
|
||||
dataInter[0::2] = dataR
|
||||
dataInter[1::2] = dataI
|
||||
print(dataInter)
|
||||
|
||||
|
||||
# In[78]:
|
||||
|
||||
|
||||
slotLen = 30720
|
||||
numSlots = 10
|
||||
slot = 6
|
||||
dataFrame = np.zeros((numSlots * slotLen,2), dtype=np.int16)
|
||||
dataFrame[slotLen*6:slotLen*6+slotLen,0] = dataR
|
||||
dataFrame[slotLen*6:slotLen*6+slotLen,1] = dataI
|
||||
write_file = 'wavejudge_input.txt'
|
||||
np.savetxt(dataPath + write_file,dataFrame,delimiter=',', fmt='%d')
|
||||
|
||||
|
||||
# In[80]:
|
||||
|
||||
|
||||
# PDSCH config
|
||||
import yaml
|
||||
|
||||
config_file = 'PDCCH_703-6_MCS22'
|
||||
config_ext = '.txt'
|
||||
with open(dataPath + config_file + config_ext, "r") as f:
|
||||
content = f.read().replace('\t', ' ') # two spaces
|
||||
|
||||
with open(dataPath + config_file + 'space' + config_ext, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
print(content)
|
||||
|
||||
|
||||
# In[107]:
|
||||
|
||||
|
||||
cell_config = {
|
||||
"dl_freq" : 1815000000,
|
||||
"frame" : 643,
|
||||
"slot" : 6,
|
||||
"cellid" : 0,
|
||||
"rnti" : 32768,
|
||||
}
|
||||
|
||||
|
||||
# In[100]:
|
||||
|
||||
|
||||
write_file = 'dlsim_input_data.bin'
|
||||
with open(dataPath + write_file, 'wb') as f:
|
||||
for key,value in cell_config.items():
|
||||
f.write(np.uint64(value).tobytes()) # write pdsch config
|
||||
dataInter.tofile(f) # Write time domain samples
|
||||
|
||||
|
||||
# In[110]:
|
||||
|
||||
|
||||
# Create bin file with sib1, rrcsetup config and samples
|
||||
sib_file = 'keysight_gnb_sib1.bin'
|
||||
rrc_file = 'keysight_gnb_rrcsetup.bin'
|
||||
write_file = 'dlsim_input_data.bin'
|
||||
with open(dataPath + write_file, 'wb') as wf:
|
||||
for key,value in cell_config.items():
|
||||
wf.write(np.uint64(value).tobytes())
|
||||
with open(dataPath + sib_file, 'rb') as f:
|
||||
data = f.read()
|
||||
wf.write(np.uint32(len(data)).tobytes())
|
||||
wf.write(data)
|
||||
with open(dataPath + rrc_file, 'rb') as f:
|
||||
data = f.read()
|
||||
wf.write(np.uint32(len(data)).tobytes())
|
||||
wf.write(data)
|
||||
wf.write(np.uint64(dataInter.size))
|
||||
dataInter.tofile(wf)
|
||||
|
||||
|
||||
# In[50]:
|
||||
|
||||
|
||||
get_ipython().system('jupyter nbconvert --to script dlsim_ext_data.ipynb')
|
||||
|
||||
|
||||
# In[ ]:
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user