Commit 26fd99ff authored by francescomani's avatar francescomani

terminal independent common functions in nr_generate_csi_rs

parent ddbbaef3
......@@ -48,31 +48,32 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss);
#endif
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
//*8(max allocation per RB)*2(QPSK))
int csi_rs_length = frame_parms->N_RB_DL << 4;
int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
uint32_t beta = amp;
// setting the frequency density from its index
double rho = 0;
switch (csi_params->freq_density) {
case 0:
rho = 0.5;
break;
case 1:
rho = 0.5;
break;
case 2:
rho = 1;
break;
case 3:
rho = 3;
break;
default:
AssertFatal(false, "Invalid frequency density index for CSI\n");
}
double rho = get_csi_rho(csi_params->freq_density);
int csi_length = get_csi_modulation_length(rho,
csi_params->freq_density,
phy_csi_parms->kprime,
csi_params->start_rb,
csi_params->nr_of_rbs);
#ifdef NR_CSIRS_DEBUG
printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length);
#endif
//*8(max allocation per RB)*2(QPSK))
int16_t mod_csi[frame_parms->symbols_per_slot][(frame_parms->N_RB_DL << 4) >> 1] __attribute__((aligned(16)));
get_modulated_csi_symbols(frame_parms->symbols_per_slot,
slot,
frame_parms->N_RB_DL,
csi_length,
mod_csi,
phy_csi_parms->lprime,
csi_params->symb_l0,
csi_params->symb_l1,
csi_params->row,
csi_params->scramb_id);
uint32_t beta = get_csi_beta_amplitude(amp, csi_params->power_control_offset_ss);
double alpha = 0;
if (phy_csi_parms->ports == 1)
alpha = rho;
......@@ -86,114 +87,20 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
// CDM group size from CDM type index
int gs = get_cdm_group_size(csi_params->cdm_type);
int kprime = phy_csi_parms->kprime;
int csi_length;
if (rho < 1) {
if (csi_params->freq_density == 0) {
csi_length = (((csi_params->start_rb + csi_params->nr_of_rbs) >> 1) << kprime) << 1;
} else {
csi_length = ((((csi_params->start_rb + csi_params->nr_of_rbs) >> 1) << kprime) + 1) << 1;
}
} else {
csi_length = (((uint16_t) rho * (csi_params->start_rb + csi_params->nr_of_rbs)) << kprime) << 1;
}
#ifdef NR_CSIRS_DEBUG
printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length);
#endif
if (csi_params->csi_type == 2) // ZP-CSI
return;
// assuming amp is the amplitude of SSB channels
switch (csi_params->power_control_offset_ss) {
case 0:
beta = (amp * ONE_OVER_SQRT2_Q15) >> 15;
break;
case 1:
beta = amp;
break;
case 2:
beta = (amp * ONE_OVER_SQRT2_Q15) >> 14;
break;
case 3:
beta = amp << 1;
break;
default:
AssertFatal(false, "Invalid SS power offset density index for CSI\n");
}
for (int lp = 0; lp <= phy_csi_parms->lprime; lp++) {
int symb = csi_params->symb_l0;
const uint32_t *gold =
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
uint8_t row = csi_params->row;
if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) {
const uint32_t *gold =
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id);
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
}
if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) {
symb = csi_params->symb_l1;
const uint32_t *gold =
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + lp, csi_params->scramb_id);
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
if ((row == 13) || (row == 16)) {
const uint32_t *gold =
nr_gold_csi_rs(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, slot, symb + 1, csi_params->scramb_id);
nr_modulation(gold, csi_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
}
}
}
int dataF_offset = slot * frame_parms->samples_per_slot_wCP;
uint16_t start_sc = frame_parms->first_carrier_offset;
// resource mapping according to 38.211 7.4.1.5.3
for (int n = csi_params->start_rb; n < (csi_params->start_rb + csi_params->nr_of_rbs); n++) {
if ((csi_params->freq_density > 1) || (csi_params->freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB
for (int ji = 0; ji < phy_csi_parms->size; ji++) { // loop over CDM groups
for (int s = 0 ; s < gs; s++) { // loop over each CDM group size
int p = s + phy_csi_parms->j[ji] * gs; // port index
for (int kp = 0; kp <= kprime; kp++) { // loop over frequency resource elements within a group
// frequency index of current resource element
int k = (start_sc + (n * NR_NB_SC_PER_RB) + phy_csi_parms->koverline[ji] + kp) % (frame_parms->ofdm_symbol_size);
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
int na = n * alpha;
int kpn = (rho * phy_csi_parms->koverline[ji]) / NR_NB_SC_PER_RB;
int mprime = na + kp + kpn; // sequence index
for (int lp = 0; lp <= phy_csi_parms->lprime; lp++) { // loop over frequency resource elements within a group
int l = lp + phy_csi_parms->loverline[ji];
// wt according to tables 7.4.5.3-2 to 7.4.5.3-5
int wt;
if (s < 2)
wt = 1;
else if (s < 4)
wt = -2 * (lp % 2) + 1;
else if (s < 6)
wt = -2 * (lp / 2) + 1;
else {
if ((lp == 0) || (lp == 3))
wt = 1;
else
wt = -1;
}
int index = ((l * frame_parms->ofdm_symbol_size + k) << 1) + (2 * dataF_offset);
((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15;
((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15;
#ifdef NR_CSIRS_DEBUG
printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",
l,
k,
mprime,
p + 3000,
((int16_t*)dataF[p])[index],
((int16_t*)dataF[p])[index + 1]);
#endif
}
}
}
}
}
}
csi_rs_resource_mapping(dataF,
frame_parms->N_RB_DL << 4,
mod_csi,
frame_parms->ofdm_symbol_size,
dataF_offset,
frame_parms->first_carrier_offset,
phy_csi_parms,
csi_params->start_rb,
csi_params->nr_of_rbs,
alpha,
beta,
rho,
gs,
csi_params->freq_density);
}
......@@ -869,6 +869,11 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
return;
}
if(csirs_config_pdu->csi_type == 2) {
LOG_E(NR_PHY, "Handling of ZP CSI-RS not handled yet at PHY\n");
return;
}
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
int16_t log2_re = 0;
......
......@@ -23,6 +23,8 @@
#define __NR_PHY_COMMON__H__
#include "PHY/impl_defs_top.h"
#include "PHY/TOOLS/tools_defs.h"
#include "PHY/NR_REFSIG/nr_refsig_common.h"
#include "PHY/MODULATION/nr_modulation.h"
typedef struct {
int size;
......@@ -33,8 +35,35 @@ typedef struct {
int koverline[16];
int loverline[16];
} csi_mapping_parms_t;
void get_modulated_csi_symbols(int symbols_per_slot,
int slot,
int N_RB_DL,
int mod_length,
int16_t mod_csi[][(N_RB_DL << 4) >> 1],
int lprime,
int l0,
int l1,
int row,
int scramb_id);
void csi_rs_resource_mapping(int32_t **dataF,
int csi_rs_length,
int16_t mod_csi[][csi_rs_length >> 1],
int ofdm_symbol_size,
int dataF_offset,
int start_sc,
const csi_mapping_parms_t *mapping_parms,
int start_rb,
int nb_rbs,
double alpha,
int beta,
double rho,
int gs,
int freq_density);
csi_mapping_parms_t get_csi_mapping_parms(int row, int b, int l0, int l1);
int get_cdm_group_size(int cdm_type);
double get_csi_rho(int freq_density);
uint32_t get_csi_beta_amplitude(const int16_t amp, int power_control_offset_ss);
int get_csi_modulation_length(double rho, int freq_density, int kprime, int start_rb, int nb_rbs);
void nr_qpsk_llr(int32_t *rxdataF_comp, int16_t *llr, uint32_t nb_re);
void nr_16qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag_in, int16_t *llr, uint32_t nb_re);
void nr_64qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int16_t *llr, uint32_t nb_re);
......
......@@ -354,6 +354,166 @@ void nr_256qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int
simde_mm_empty();
}
void csi_rs_resource_mapping(int32_t **dataF,
int csi_rs_length,
int16_t mod_csi[][csi_rs_length >> 1],
int ofdm_symbol_size,
int dataF_offset,
int start_sc,
const csi_mapping_parms_t *mapping_parms,
int start_rb,
int nb_rbs,
double alpha,
int beta,
double rho,
int gs,
int freq_density)
{
// resource mapping according to 38.211 7.4.1.5.3
for (int n = start_rb; n < (start_rb + nb_rbs); n++) {
if ((freq_density > 1) || (freq_density == (n % 2))) { // for freq density 0.5 checks if even or odd RB
for (int ji = 0; ji < mapping_parms->size; ji++) { // loop over CDM groups
for (int s = 0 ; s < gs; s++) { // loop over each CDM group size
int p = s + mapping_parms->j[ji] * gs; // port index
for (int kp = 0; kp <= mapping_parms->kprime; kp++) { // loop over frequency resource elements within a group
// frequency index of current resource element
int k = (start_sc + (n * NR_NB_SC_PER_RB) + mapping_parms->koverline[ji] + kp) % (ofdm_symbol_size);
// wf according to tables 7.4.5.3-2 to 7.4.5.3-5
int wf = kp == 0 ? 1 : (-2 * (s % 2) + 1);
int na = n * alpha;
int kpn = (rho * mapping_parms->koverline[ji]) / NR_NB_SC_PER_RB;
int mprime = na + kp + kpn; // sequence index
for (int lp = 0; lp <= mapping_parms->lprime; lp++) { // loop over frequency resource elements within a group
int l = lp + mapping_parms->loverline[ji];
// wt according to tables 7.4.5.3-2 to 7.4.5.3-5
int wt;
if (s < 2)
wt = 1;
else if (s < 4)
wt = -2 * (lp % 2) + 1;
else if (s < 6)
wt = -2 * (lp / 2) + 1;
else {
if ((lp == 0) || (lp == 3))
wt = 1;
else
wt = -1;
}
int index = ((l * ofdm_symbol_size + k) << 1) + (2 * dataF_offset);
((int16_t*)dataF[p])[index] = (beta * wt * wf * mod_csi[l][mprime << 1]) >> 15;
((int16_t*)dataF[p])[index + 1] = (beta * wt * wf * mod_csi[l][(mprime << 1) + 1]) >> 15;
LOG_D(PHY,
"l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",
l,
k,
mprime,
p + 3000,
((int16_t*)dataF[p])[index],
((int16_t*)dataF[p])[index + 1]);
}
}
}
}
}
}
}
void get_modulated_csi_symbols(int symbols_per_slot,
int slot,
int N_RB_DL,
int mod_length,
int16_t mod_csi[][(N_RB_DL << 4) >> 1],
int lprime,
int l0,
int l1,
int row,
int scramb_id)
{
for (int lp = 0; lp <= lprime; lp++) {
int symb = l0;
const uint32_t *gold =
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + lp, scramb_id);
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
if ((row == 5) || (row == 7) || (row == 11) || (row == 13) || (row == 16)) {
const uint32_t *gold =
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + 1, scramb_id);
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
}
if ((row == 14) || (row == 13) || (row == 16) || (row == 17)) {
symb = l1;
const uint32_t *gold =
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + lp, scramb_id);
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + lp]);
if ((row == 13) || (row == 16)) {
const uint32_t *gold =
nr_gold_csi_rs(N_RB_DL, symbols_per_slot, slot, symb + 1, scramb_id);
nr_modulation(gold, mod_length, DMRS_MOD_ORDER, mod_csi[symb + 1]);
}
}
}
}
uint32_t get_csi_beta_amplitude(const int16_t amp, int power_control_offset_ss)
{
uint32_t beta = amp;
// assuming amp is the amplitude of SSB channels
switch (power_control_offset_ss) {
case 0:
beta = (amp * ONE_OVER_SQRT2_Q15) >> 15;
break;
case 1:
beta = amp;
break;
case 2:
beta = (amp * ONE_OVER_SQRT2_Q15) >> 14;
break;
case 3:
beta = amp << 1;
break;
default:
AssertFatal(false, "Invalid SS power offset density index for CSI\n");
}
return beta;
}
int get_csi_modulation_length(double rho, int freq_density, int kprime, int start_rb, int nr_rbs)
{
int csi_length = 0;
if (rho < 1) {
if (freq_density == 0) {
csi_length = (((start_rb + nr_rbs) >> 1) << kprime) << 1;
} else {
csi_length = ((((start_rb + nr_rbs) >> 1) << kprime) + 1) << 1;
}
} else {
csi_length = (((uint16_t) rho * (start_rb + nr_rbs)) << kprime) << 1;
}
return csi_length;
}
double get_csi_rho(int freq_density)
{
// setting the frequency density from its index
double rho = 0;
switch (freq_density) {
case 0:
rho = 0.5;
break;
case 1:
rho = 0.5;
break;
case 2:
rho = 1;
break;
case 3:
rho = 3;
break;
default:
AssertFatal(false, "Invalid frequency density index for CSI\n");
}
return rho;
}
int get_cdm_group_size(int cdm_type)
{
// CDM group size from CDM type index
......
......@@ -220,6 +220,10 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
if (csirs->active == 1) {
LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
if (csi_params->csi_type == 2) { // ZP-CSI
csirs->active = 0;
return;
}
csi_mapping_parms_t mapping_parms = get_csi_mapping_parms(csi_params->row,
csi_params->freq_domain,
csi_params->symb_l0,
......
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