mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-15 05:30:29 +00:00
Compare commits
24 Commits
pre-commit
...
SL_L1_inte
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0927b58ff | ||
|
|
fac4760bc8 | ||
|
|
22f5b3b3ba | ||
|
|
2fae82250e | ||
|
|
ae3a2115cd | ||
|
|
3926a060fa | ||
|
|
e73133f764 | ||
|
|
aca3824fde | ||
|
|
a44481ae85 | ||
|
|
80fc10423b | ||
|
|
88ff8e2a2f | ||
|
|
b0c6e23dd4 | ||
|
|
1f3fe83c96 | ||
|
|
c55a4bb0c5 | ||
|
|
046ec8d839 | ||
|
|
56a97fdc20 | ||
|
|
d503df5dc4 | ||
|
|
5b277d1eec | ||
|
|
81b433fc1c | ||
|
|
4fbdf73f08 | ||
|
|
b39d9dd0ef | ||
|
|
45bccc3d73 | ||
|
|
5e7f4e38d0 | ||
|
|
d5061cf12d |
@@ -1019,16 +1019,22 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pscch_tx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psfch_tx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/csi_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/csi_sl_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_slsch_decoding.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_slsch_demodulation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_slsch_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_prach.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_sci.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/csi_rx.c
|
||||
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
||||
@@ -1038,6 +1044,7 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_sl_channel_estimation.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c
|
||||
@@ -1924,6 +1931,8 @@ target_link_libraries(nr-uesoftmodem PRIVATE
|
||||
time_management softmodem_common
|
||||
-Wl,--end-group dl)
|
||||
|
||||
# TODO for sidelink
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE PHY_NR)
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE pthread m CONFIG_LIB rt nr_ue_phy_meas)
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE ${T_LIB})
|
||||
target_link_libraries(nr-uesoftmodem PRIVATE nr_nas lib_uicc usim_lib SECURITY)
|
||||
|
||||
@@ -1457,3 +1457,237 @@ void nr_deconstruct_5g_s_tmsi(const uint64_t fiveg_s_tmsi, uint16_t *amf_set_id,
|
||||
*amf_pointer = (fiveg_s_tmsi >> 32) & 0x3F;
|
||||
*m_tmsi = fiveg_s_tmsi;
|
||||
}
|
||||
|
||||
// the following tables contain 10 times the value reported in 214 (in line with SCF specification and to avoid fractional values)
|
||||
//Table 5.1.3.1-1 of 38.214
|
||||
static const uint16_t Table_51311[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
|
||||
{2, 6020}, {2, 6790}, {4, 3400}, {4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160},
|
||||
{4, 6580}, {6, 4380}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7190},
|
||||
{6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
// Table 5.1.3.1-2 of 38.214
|
||||
static const uint16_t Table_51312[32][2] = {{2, 1200}, {2, 1930}, {2, 3080}, {2, 4490}, {2, 6020}, {4, 3780}, {4, 4340},
|
||||
{4, 4900}, {4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670},
|
||||
{6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {8, 6825},
|
||||
{8, 7110}, {8, 7540}, {8, 7970}, {8, 8410}, {8, 8850}, {8, 9165}, {8, 9480},
|
||||
{2, 0}, {4, 0}, {6, 0}, {8, 0}};
|
||||
|
||||
//Table 5.1.3.1-3 of 38.214
|
||||
static const uint16_t Table_51313[32][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200}, {2, 1570},
|
||||
{2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260}, {2, 6020}, {4, 3400},
|
||||
{4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160}, {6, 4380}, {6, 4660}, {6, 5170},
|
||||
{6, 5670}, {6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
static const uint16_t Table_61411[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490},
|
||||
{2, 5260}, {2, 6020}, {2, 6790}, {4, 3400}, {4, 3780}, {4, 4340}, {4, 4900},
|
||||
{4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160},
|
||||
{6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480},
|
||||
{2, 0}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
static const uint16_t Table_61412[32][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200},
|
||||
{2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
|
||||
{2, 6020}, {2, 6790}, {4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160},
|
||||
{4, 6580}, {4, 6990}, {4, 7720}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7720},
|
||||
{2, 0}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61411[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61412[Imcs][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61411[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61412[Imcs][1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define MAX_EL_213_9_3_2 19
|
||||
const float tab38_213_9_3_2[MAX_EL_213_9_3_2] = {1.125,1.250,1.375,1.625,1.750,2.000,2.250,2.500,2.875,3.125,3.500,4.000,5.000,6.250,8.000,10.000,12.625,15.875,20.000};
|
||||
|
||||
int get_NREsci2(const int sci2_alpha,
|
||||
const int sci2_payload_len,
|
||||
const int sci2_beta_offset,
|
||||
const int pssch_numsym,
|
||||
const int pscch_numsym,
|
||||
const int pscch_numrbs,
|
||||
const int l_subch,
|
||||
const int subchannel_size,
|
||||
const int target_coderate) {
|
||||
|
||||
float Osci2 = (float)sci2_payload_len;
|
||||
AssertFatal(sci2_beta_offset < MAX_EL_213_9_3_2, "illegal sci2_beta_offset %d\n",sci2_beta_offset);
|
||||
float beta_offset_sci2 = tab38_213_9_3_2[sci2_beta_offset];
|
||||
|
||||
uint32_t R10240 = target_coderate;
|
||||
uint32_t tmp = (uint32_t)ceil((Osci2 + 24)*beta_offset_sci2/((float)R10240/5120));
|
||||
float tmp2 = 12.0*pssch_numsym;
|
||||
int N_REsci1 = 12*pscch_numrbs*pscch_numsym;
|
||||
tmp2 *= l_subch*subchannel_size;
|
||||
tmp2 -= N_REsci1;
|
||||
tmp2 *= ((float)sci2_alpha/100.0);
|
||||
int min_val = min(tmp,(int)ceil(tmp2));
|
||||
uint8_t gamma = 12 - (min_val % 12);
|
||||
return min_val + (gamma % 12);
|
||||
}
|
||||
|
||||
int get_nRECSI_RS(uint8_t freq_density,
|
||||
uint16_t nr_of_rbs,
|
||||
int nb_antennas_tx) {
|
||||
AssertFatal(freq_density > 0, "freq_density must be greater than 1\n");
|
||||
uint8_t nr_rbs_w_csi_rs = nr_of_rbs / freq_density;
|
||||
// Actually, kprime + 1 sub-carriers are used by csi-rs. kprime can be 0 or 1 but nb_antennas_tx can be greater than 2.
|
||||
uint8_t subcarriers_used = nb_antennas_tx > 2 ? 2 : nb_antennas_tx;
|
||||
return nr_rbs_w_csi_rs * subcarriers_used;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -369,6 +369,28 @@ uint64_t nr_build_full_5g_s_tmsi(const uint64_t part1, const uint16_t part2);
|
||||
/** @brief Deconstruct full 5G-S-TMSI into its components */
|
||||
void nr_deconstruct_5g_s_tmsi(const uint64_t fiveg_s_tmsi, uint16_t *amf_set_id, uint8_t *amf_pointer, uint32_t *m_tmsi);
|
||||
|
||||
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
|
||||
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
|
||||
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
|
||||
|
||||
/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
|
||||
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
|
||||
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
|
||||
|
||||
/** @brief Helper for SL CSI in UE */
|
||||
int get_nRECSI_RS(uint8_t freq_density, uint16_t nr_of_rbs, int nb_antennas_tx);
|
||||
|
||||
/** @brief Helper for SL SCI2 in UE */
|
||||
int get_NREsci2(const int sci2_alpha,
|
||||
const int sci2_payload_len,
|
||||
const int sci2_beta_offset,
|
||||
const int pssch_numsym,
|
||||
const int pscch_numsym,
|
||||
const int pscch_numrbs,
|
||||
const int l_subch,
|
||||
const int subchannel_size,
|
||||
const int target_coderate);
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b)))
|
||||
|
||||
@@ -117,12 +117,6 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
|
||||
}
|
||||
|
||||
|
||||
#define KNRM "\x1B[0m"
|
||||
#define KRED "\x1B[31m"
|
||||
#define KGRN "\x1B[32m"
|
||||
#define KBLU "\x1B[34m"
|
||||
#define RESET "\033[0m"
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
{
|
||||
int ru_id;
|
||||
|
||||
@@ -554,7 +554,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
|
||||
}
|
||||
|
||||
sampleShift = pbch_processing(UE, proc, phy_data);
|
||||
pdcch_processing(UE, proc, phy_data);
|
||||
pdcch_processing(UE, proc, phy_data,0);
|
||||
if (phy_data->dlsch[0].active
|
||||
&& (phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_ || phy_data->dlsch[0].rnti_type == TYPE_RA_RNTI_)) {
|
||||
// indicate to tx thread to wait for DLSCH decoding
|
||||
@@ -590,7 +590,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
|
||||
AssertFatal((phy_data->sl_rx_action >= SL_NR_CONFIG_TYPE_RX_PSBCH &&
|
||||
phy_data->sl_rx_action < SL_NR_CONFIG_TYPE_RX_MAXIMUM), "Incorrect SL RX Action Scheduled\n");
|
||||
|
||||
sampleShift = psbch_pscch_processing(UE, proc, phy_data);
|
||||
sampleShift = psbch_pscch_pssch_processing(UE, proc, phy_data);
|
||||
}
|
||||
}
|
||||
} else
|
||||
|
||||
@@ -83,6 +83,19 @@ uint64_t sidelink_frequency[MAX_NUM_CCs][4];
|
||||
// UE and OAI config variables
|
||||
double cpuf;
|
||||
|
||||
// TODO sidelink: avoid linker errors for including gNB
|
||||
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { abort(); return NULL; }
|
||||
int get_nr_prach_duration(uint8_t prach_format) { abort(); return 0; }
|
||||
int beam_index_allocation(bool das,
|
||||
int fapi_beam_index,
|
||||
NR_gNB_COMMON *common_vars,
|
||||
int slot,
|
||||
int symbols_per_slot,
|
||||
int bitmap_symbols)
|
||||
{
|
||||
abort(); return 0;
|
||||
}
|
||||
|
||||
int create_tasks_nrue(uint32_t ue_nb) {
|
||||
LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
|
||||
itti_wait_ready(1);
|
||||
|
||||
@@ -321,6 +321,13 @@ extern char *parallel_config;
|
||||
extern char *worker_config;
|
||||
extern double cpuf;
|
||||
|
||||
|
||||
#define KNRM "\x1B[0m"
|
||||
#define KRED "\x1B[31m"
|
||||
#define KGRN "\x1B[32m"
|
||||
#define KBLU "\x1B[34m"
|
||||
#define RESET "\033[0m"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#define SL_NR_RX_CONFIG_LIST_NUM 1
|
||||
#define SL_NR_TX_CONFIG_LIST_NUM 1
|
||||
#define SL_NR_RX_IND_MAX_PDU 1
|
||||
#define SL_NR_RX_IND_MAX_PDU 2
|
||||
#define SL_NR_SCI_IND_MAX_PDU 2
|
||||
#define SL_NR_MAX_PSCCH_SCI_LENGTH_IN_BYTES 8
|
||||
#define SL_NR_MAX_PSSCH_SCI_LENGTH_IN_BYTES 8
|
||||
#define SL_NR_MAX_SCI_LENGTH_IN_BYTES 8
|
||||
@@ -24,7 +25,8 @@ typedef enum sl_sci_format_type_enum {
|
||||
typedef enum sl_rx_pdu_type_enum {
|
||||
SL_NR_RX_PDU_TYPE_NONE,
|
||||
SL_NR_RX_PDU_TYPE_SSB,
|
||||
SL_NR_RX_PDU_TYPE_SLSCH
|
||||
SL_NR_RX_PDU_TYPE_SLSCH,
|
||||
SL_NR_RX_PDU_TYPE_SLSCH_PSFCH
|
||||
} sl_rx_pdu_type_enum_t;
|
||||
|
||||
//Type of SL-RX CONFIG requests from MAC to PHY
|
||||
@@ -33,7 +35,8 @@ typedef enum sl_nr_rx_config_type_enum {
|
||||
SL_NR_CONFIG_TYPE_RX_PSCCH,
|
||||
SL_NR_CONFIG_TYPE_RX_PSSCH_SCI,
|
||||
SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH,
|
||||
SL_NR_CONFIG_TYPE_RX_PSFCH,
|
||||
SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_PSFCH,
|
||||
SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_CSI_RS,
|
||||
SL_NR_CONFIG_TYPE_RX_MAXIMUM
|
||||
} sl_nr_rx_config_type_enum_t;
|
||||
|
||||
@@ -41,7 +44,8 @@ typedef enum sl_nr_rx_config_type_enum {
|
||||
typedef enum sl_nr_tx_config_type_enum {
|
||||
SL_NR_CONFIG_TYPE_TX_PSBCH = SL_NR_CONFIG_TYPE_RX_MAXIMUM + 1,
|
||||
SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH,
|
||||
SL_NR_CONFIG_TYPE_TX_PSFCH,
|
||||
SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_PSFCH,
|
||||
SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS,
|
||||
SL_NR_CONFIG_TYPE_TX_MAXIMUM
|
||||
} sl_nr_tx_config_type_enum_t;
|
||||
|
||||
@@ -73,7 +77,7 @@ typedef struct {
|
||||
uint8_t sensing_result;
|
||||
//in case pssch sensing is requested.
|
||||
int16_t pssch_rsrp;
|
||||
sl_nr_sci_indication_pdu_t sci_pdu;
|
||||
sl_nr_sci_indication_pdu_t sci_pdu[SL_NR_SCI_IND_MAX_PDU];
|
||||
} sl_nr_sci_indication_t;
|
||||
|
||||
// IF UE Rx PSBCH, PHY indicates MAC with received MIB and PSBCH RSRP
|
||||
@@ -84,8 +88,14 @@ typedef struct sl_nr_ssb_pdu {
|
||||
bool decode_status;
|
||||
} sl_nr_ssb_pdu_t;
|
||||
|
||||
//Use the same structure of pdsch pdu for slsch pdu
|
||||
typedef fapi_nr_pdsch_pdu_t sl_nr_slsch_pdu_t;
|
||||
typedef struct sl_nr_slsch_pdu {
|
||||
uint8_t harq_pid;
|
||||
uint8_t ack_nack;
|
||||
uint8_t *ack_nack_rcvd;
|
||||
uint8_t num_acks_rcvd;
|
||||
uint32_t pdu_length;
|
||||
uint8_t* pdu;
|
||||
} sl_nr_slsch_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
sl_rx_pdu_type_enum_t pdu_type;
|
||||
@@ -195,6 +205,40 @@ typedef struct sl_nr_rx_config_pssch_pdu {
|
||||
uint8_t ndi;
|
||||
} sl_nr_rx_config_pssch_pdu_t;
|
||||
|
||||
typedef struct sl_nr_tx_rx_config_psfch_pdu {
|
||||
// These fields can be mapped directly to the same fields
|
||||
uint8_t freq_hop_flag;
|
||||
uint8_t group_hop_flag;
|
||||
uint8_t sequence_hop_flag;
|
||||
uint16_t second_hop_prb;
|
||||
uint8_t nr_of_symbols;
|
||||
uint8_t start_symbol_index;
|
||||
uint8_t hopping_id;
|
||||
uint16_t prb;
|
||||
uint16_t sl_bwp_start;
|
||||
uint16_t initial_cyclic_shift;
|
||||
uint8_t mcs;
|
||||
uint8_t bit_len_harq;
|
||||
} sl_nr_tx_rx_config_psfch_pdu_t;
|
||||
|
||||
typedef struct sl_nr_tti_csi_rs_pdu {
|
||||
uint8_t subcarrier_spacing;
|
||||
uint8_t cyclic_prefix;
|
||||
uint16_t start_rb;
|
||||
uint16_t nr_of_rbs;
|
||||
uint8_t csi_type;
|
||||
uint8_t row;
|
||||
uint16_t freq_domain;
|
||||
uint8_t symb_l0;
|
||||
uint8_t symb_l1;
|
||||
uint8_t cdm_type;
|
||||
uint8_t freq_density;
|
||||
uint16_t scramb_id;
|
||||
uint8_t power_control_offset;
|
||||
uint8_t power_control_offset_ss;
|
||||
uint8_t measurement_bitmap;
|
||||
} sl_nr_tti_csi_rs_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
sl_nr_rx_config_type_enum_t pdu_type; // indicates the type of RX config request
|
||||
union {
|
||||
@@ -202,6 +246,9 @@ typedef struct {
|
||||
sl_nr_rx_config_pssch_sci_pdu_t rx_sci2_config_pdu;
|
||||
sl_nr_rx_config_pssch_pdu_t rx_pssch_config_pdu;
|
||||
};
|
||||
sl_nr_tti_csi_rs_pdu_t rx_csi_rs_config_pdu;
|
||||
sl_nr_tx_rx_config_psfch_pdu_t *rx_psfch_pdu_list;
|
||||
uint16_t num_psfch_pdus;
|
||||
} sl_nr_rx_config_request_pdu_t;
|
||||
|
||||
// MAC commands PHY to perform an action on RX RESOURCE POOL or RX PSBCH using this RX CONFIG
|
||||
@@ -247,7 +294,8 @@ typedef struct sl_nr_tx_config_pscch_pssch_pdu {
|
||||
//Guard symbol + AGC symbol are also excluded
|
||||
//Indicates the number of symbols for PSCCH+PSSCH txn
|
||||
uint8_t pssch_numsym;
|
||||
|
||||
// start symbol of PSCCH/PSSCH (excluding AGC)
|
||||
uint8_t pssch_startsym;
|
||||
//.... Other Parameters for SCI-2 and PSSCH
|
||||
|
||||
// Used to determine number of SCI2 modulated symbols
|
||||
@@ -270,14 +318,21 @@ typedef struct sl_nr_tx_config_pscch_pssch_pdu {
|
||||
// Table from SPEC 38.211, Table 8.4.1.1.2-1
|
||||
uint16_t dmrs_symbol_position;
|
||||
|
||||
|
||||
//....TBD.. any additional parameters
|
||||
// PSFCH related parameters
|
||||
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu_list;
|
||||
uint16_t num_psfch_pdus;
|
||||
|
||||
// CSI-RS related parameters
|
||||
sl_nr_tti_csi_rs_pdu_t nr_sl_csi_rs_pdu;
|
||||
|
||||
//TX Power for PSSCH in symbol without PSCCH.
|
||||
// Power for PSCCH and power for PSSCH in symbol with PSCCH is calculated
|
||||
// from this value according to 38.213 section 16
|
||||
int16_t pssch_tx_power;
|
||||
|
||||
uint16_t slsch_payload_length;
|
||||
uint8_t *slsch_payload;
|
||||
|
||||
} sl_nr_tx_config_pscch_pssch_pdu_t;
|
||||
|
||||
// MAC indicates PHY to send PSBCH.
|
||||
@@ -386,8 +441,26 @@ typedef struct {
|
||||
fapi_nr_tdd_table_t tdd_table;
|
||||
//only 1 SL-BWP can be configured in REL16, REL17
|
||||
sl_nr_bwp_config_t sl_bwp_config;
|
||||
|
||||
// scrambling ID used for PSSCH SCI transmissions
|
||||
uint32_t sl_DMRS_ScrambleId;
|
||||
} sl_nr_phy_config_request_t;
|
||||
|
||||
/* Dependencies */
|
||||
typedef enum NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR {
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_NOTHING, /* No components present */
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots4,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots5,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots8,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots10,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots16,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots20,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots32,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots40,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots64,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots80,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots160,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots320,
|
||||
NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR_slots640
|
||||
} NR_UE_SL_CSI_ResourcePeriodicityAndOffset_PR;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -306,6 +306,7 @@ int main(int argc, char *argv[])
|
||||
if (decoder_int16 == 1) {
|
||||
decoderState = polar_decoder_int16(channelOutput_int16,
|
||||
(uint64_t *)estimatedOutput,
|
||||
(uint16_t *)NULL,
|
||||
0,
|
||||
polarMessageType,
|
||||
testLength,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#define __NR_POLAR_DCI_DEFS__H__
|
||||
|
||||
#define NR_POLAR_DCI_MESSAGE_TYPE 1 // int8_t
|
||||
#define NR_POLAR_SCI_MESSAGE_TYPE (NR_POLAR_PSBCH_MESSAGE_TYPE + 1) //int8_t
|
||||
#define NR_POLAR_SCI2_MESSAGE_TYPE (NR_POLAR_SCI_MESSAGE_TYPE + 1) //int8_t
|
||||
#define NR_POLAR_DCI_CRC_PARITY_BITS 24
|
||||
#define NR_POLAR_DCI_CRC_ERROR_CORRECTION_BITS 3
|
||||
|
||||
|
||||
@@ -643,6 +643,7 @@ static inline void nr_polar_info_extraction_from_u(uint64_t *Cprime,
|
||||
|
||||
uint32_t polar_decoder_int16(int16_t *input,
|
||||
uint64_t *out,
|
||||
uint16_t *nid,
|
||||
uint8_t ones_flag,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
@@ -817,6 +818,7 @@ uint32_t polar_decoder_int16(int16_t *input,
|
||||
|
||||
out[0] = Ar;
|
||||
|
||||
if (nid) *nid=crc&65535;
|
||||
polarReturn(polarParams);
|
||||
return crc ^ rxcrc;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,7 @@ int8_t polar_decoder(double *input,
|
||||
|
||||
uint32_t polar_decoder_int16(int16_t *input,
|
||||
uint64_t *out,
|
||||
uint16_t *nid,
|
||||
uint8_t ones_flag,
|
||||
int8_t messageType,
|
||||
uint16_t messageLength,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
#include "PHY/NR_REFSIG/pss_nr.h"
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
#include "PHY/NR_REFSIG/sl_refsig_defs.h"
|
||||
@@ -368,8 +369,10 @@ void term_nr_ue_transport(PHY_VARS_NR_UE *ue)
|
||||
{
|
||||
const int N_RB_DL = ue->frame_parms.N_RB_DL;
|
||||
const int N_RB_UL = ue->frame_parms.N_RB_UL;
|
||||
const int N_RB_SL = ue->SL_UE_PHY_PARAMS.sl_frame_params.N_RB_UL;
|
||||
free_nr_ue_dl_harq(ue->dl_harq_processes, NR_MAX_HARQ_PROCESSES, N_RB_DL);
|
||||
free_nr_ue_ul_harq(ue->ul_harq_processes, NR_MAX_HARQ_PROCESSES, N_RB_UL, ue->frame_parms.nb_antennas_tx);
|
||||
free_nr_ue_ul_harq(ue->sl_harq_processes, NR_MAX_HARQ_PROCESSES, N_RB_SL, ue->SL_UE_PHY_PARAMS.sl_frame_params.nb_antennas_tx);
|
||||
}
|
||||
|
||||
void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_HARQ_PROCESSES], int number_of_processes, int num_rb)
|
||||
@@ -448,6 +451,7 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue)
|
||||
{
|
||||
nr_init_dl_harq_processes(ue->dl_harq_processes, NR_MAX_HARQ_PROCESSES, ue->frame_parms.N_RB_DL);
|
||||
nr_init_ul_harq_processes(ue->ul_harq_processes, NR_MAX_HARQ_PROCESSES, ue->frame_parms.N_RB_UL, ue->frame_parms.nb_antennas_tx);
|
||||
nr_init_ul_harq_processes(ue->sl_harq_processes, NR_MAX_HARQ_PROCESSES, ue->SL_UE_PHY_PARAMS.sl_frame_params.N_RB_UL, ue->frame_parms.nb_antennas_tx);
|
||||
}
|
||||
|
||||
void clean_UE_harq(PHY_VARS_NR_UE *UE)
|
||||
@@ -531,4 +535,66 @@ void sl_ue_phy_init(PHY_VARS_NR_UE *UE)
|
||||
// Generate PSS time domain samples used for correlation during SLSS reception.
|
||||
sl_generate_pss_ifft_samples(&UE->SL_UE_PHY_PARAMS, &UE->SL_UE_PHY_PARAMS.init_params);
|
||||
|
||||
// PSCCH DMRS gold sequences (TX)
|
||||
UE->nr_gold_pscch_dmrs = (uint32_t ***)malloc16(sl_fp->slots_per_frame * sizeof(uint32_t **));
|
||||
uint32_t ***pscch_dmrs = UE->nr_gold_pscch_dmrs;
|
||||
AssertFatal(pscch_dmrs != NULL, "NR SL UE init: pscch_dmrs malloc failed\n");
|
||||
int pscch_dmrs_init_length = (((sl_fp->N_RB_UL << 1) * 3) >> 5) + 1;
|
||||
|
||||
for (int slot = 0; slot < sl_fp->slots_per_frame; slot++) {
|
||||
pscch_dmrs[slot] = (uint32_t **)malloc16(sl_fp->symbols_per_slot * sizeof(uint32_t *));
|
||||
AssertFatal(pscch_dmrs[slot] != NULL, "NR SL UE init: pscch_dmrs for slot %d - malloc failed\n", slot);
|
||||
for (int symb = 0; symb < sl_fp->symbols_per_slot; symb++) {
|
||||
pscch_dmrs[slot][symb] = (uint32_t *)malloc16(pscch_dmrs_init_length * sizeof(uint32_t));
|
||||
AssertFatal(pscch_dmrs[slot][symb] != NULL, "NR SL UE init: pscch_dmrs slot %d symb %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
nr_init_pscch_dmrs(sl_fp,UE->nr_gold_pscch_dmrs, UE->SL_UE_PHY_PARAMS.sl_config.sl_DMRS_ScrambleId);
|
||||
|
||||
// PSCCH DMRS gold sequences (RX)
|
||||
UE->nr_gold_pscch = (uint32_t ***)malloc16(sl_fp->slots_per_frame * sizeof(uint32_t **));
|
||||
uint32_t ***pscch_dmrs_rx = UE->nr_gold_pscch;
|
||||
AssertFatal(pscch_dmrs_rx != NULL, "NR SL UE init: pscch_dmrs_rx malloc failed\n");
|
||||
|
||||
for (int slot = 0; slot < sl_fp->slots_per_frame; slot++) {
|
||||
pscch_dmrs_rx[slot] = (uint32_t **)malloc16(sl_fp->symbols_per_slot * sizeof(uint32_t *));
|
||||
AssertFatal(pscch_dmrs_rx[slot] != NULL, "NR SL UE init: pscch_dmrs_rx for slot %d - malloc failed\n", slot);
|
||||
for (int symb = 0; symb < sl_fp->symbols_per_slot; symb++) {
|
||||
pscch_dmrs_rx[slot][symb] = (uint32_t *)malloc16(pscch_dmrs_init_length * sizeof(uint32_t));
|
||||
AssertFatal(pscch_dmrs_rx[slot][symb] != NULL, "NR SL UE init: pscch_dmrs_rx slot %d symb %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
nr_init_pscch_dmrs(sl_fp, pscch_dmrs_rx, UE->SL_UE_PHY_PARAMS.sl_config.sl_DMRS_ScrambleId);
|
||||
|
||||
// SLSCH allocation
|
||||
UE->max_nb_slsch = NR_SLSCH_RX_MAX;
|
||||
UE->slsch = (NR_gNB_ULSCH_t *)malloc16(UE->max_nb_slsch * sizeof(NR_gNB_ULSCH_t));
|
||||
for (int i = 0; i < UE->max_nb_slsch; i++) {
|
||||
LOG_I(PHY, "Allocating Transport Channel Buffers for SLSCH %d/%d\n", i, UE->max_nb_slsch);
|
||||
UE->slsch[i] = new_gNB_ulsch(UE->max_ldpc_iterations, sl_fp->N_RB_UL);
|
||||
}
|
||||
|
||||
// PSSCH vars allocation
|
||||
int Prx = sl_fp->nb_antennas_rx;
|
||||
int N_RB_UL = sl_fp->N_RB_UL;
|
||||
int n_buf = 2 * Prx;
|
||||
int nb_re_pusch = N_RB_UL * NR_NB_SC_PER_RB;
|
||||
int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch & 7);
|
||||
UE->pssch_thres = 10;
|
||||
UE->pssch_vars = (NR_gNB_PUSCH *)malloc16_clear(UE->max_nb_slsch * sizeof(NR_gNB_PUSCH));
|
||||
for (int SLSCH_id = 0; SLSCH_id < NR_SLSCH_RX_MAX; SLSCH_id++) {
|
||||
NR_gNB_PUSCH *pssch = &UE->pssch_vars[SLSCH_id];
|
||||
pssch->ul_ch_estimates = malloc16(n_buf * sizeof(int32_t *));
|
||||
pssch->rxdataF_comp = malloc16(n_buf * sizeof(int32_t *));
|
||||
for (int i = 0; i < n_buf; i++) {
|
||||
pssch->ul_ch_estimates[i] = malloc16_clear(sizeof(int32_t) * sl_fp->ofdm_symbol_size * sl_fp->symbols_per_slot);
|
||||
pssch->rxdataF_comp[i] = malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * sl_fp->symbols_per_slot);
|
||||
}
|
||||
pssch->llr = malloc16_clear((8 * ((3 * 8 * 6144) + 12)) * sizeof(int16_t));
|
||||
pssch->ul_valid_re_per_slot = malloc16_clear(sizeof(int16_t) * sl_fp->symbols_per_slot);
|
||||
}
|
||||
|
||||
// UE->sl_measurements = calloc(1, sizeof(struct PHY_MEASUREMENTS_gNB_s));
|
||||
|
||||
init_delay_table(sl_fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, sl_fp->delay_table);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,48 @@
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
#include "sl_refsig_defs.h"
|
||||
#include "openair1/PHY/gold.h"
|
||||
#include "sl_refsig_defs.h"
|
||||
#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
void nr_init_pscch_dmrs(NR_DL_FRAME_PARMS *fp, uint32_t ***nr_gold, uint16_t nid)
|
||||
{
|
||||
unsigned int n = 0, x1 = 0, x2 = 0, x2tmp0 = 0;
|
||||
uint8_t reset;
|
||||
int pdcch_dmrs_init_length = (((fp->N_RB_UL << 1) * 3) >> 5) + 1;
|
||||
|
||||
for (int ns = 0; ns < fp->slots_per_frame; ns++) {
|
||||
for (int l = 0; l < fp->symbols_per_slot; l++) {
|
||||
reset = 1;
|
||||
x2tmp0 = ((fp->symbols_per_slot * ns + l + 1) * ((nid << 1) + 1));
|
||||
x2tmp0 <<= 17;
|
||||
x2 = (x2tmp0 + (nid << 1)) % (1U << 31); //cinit
|
||||
for (n=0; n<pdcch_dmrs_init_length; n++) {
|
||||
nr_gold[ns][l][n] = gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_init_pssch_dmrs_oneshot(NR_DL_FRAME_PARMS *fp,
|
||||
uint16_t N_id,
|
||||
uint32_t *pssch_dmrs,
|
||||
int slot,
|
||||
int symb)
|
||||
{
|
||||
uint32_t x1 = 0, x2 = 0, n = 0;
|
||||
int pusch_dmrs_init_length = ((fp->N_RB_UL * 12) >> 5) + 1;
|
||||
|
||||
int reset = 1;
|
||||
x2 = ((1U << 17) * (fp->symbols_per_slot*slot + symb + 1) * ((N_id << 1) + 1) + (N_id << 1));
|
||||
LOG_D(PHY,"PSSCH DMRS slot %d, symb %d x2 %x\n", slot, symb, x2);
|
||||
for (n=0; n<pusch_dmrs_init_length; n++) {
|
||||
pssch_dmrs[n] = gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
|
||||
{
|
||||
|
||||
@@ -7,8 +7,44 @@
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
typedef struct port_freq_indices {
|
||||
uint8_t p;
|
||||
uint16_t k;
|
||||
} port_freq_indices_t;
|
||||
|
||||
typedef struct csi_rs_params {
|
||||
uint8_t size;
|
||||
uint8_t j[16];
|
||||
uint8_t k_n[6];
|
||||
uint8_t kprime;
|
||||
uint8_t lprime;
|
||||
uint8_t ports;
|
||||
uint8_t koverline[16];
|
||||
uint8_t loverline[16];
|
||||
double rho;
|
||||
double alpha;
|
||||
uint8_t gs;
|
||||
} csi_rs_params_t;
|
||||
|
||||
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
|
||||
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);
|
||||
void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling);
|
||||
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE);
|
||||
|
||||
void nr_init_pscch_dmrs(NR_DL_FRAME_PARMS *fp, uint32_t ***nr_gold, uint16_t nid);
|
||||
|
||||
void nr_init_pssch_dmrs_oneshot(NR_DL_FRAME_PARMS *fp,
|
||||
uint16_t N_id,
|
||||
uint32_t *pssch_dmrs,
|
||||
int slot,
|
||||
int symb);
|
||||
|
||||
void get_csi_rs_freq_ind_sl(const NR_DL_FRAME_PARMS* frame_parms,
|
||||
uint16_t n,
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* csi_params,
|
||||
csi_rs_params_t* table_params,
|
||||
port_freq_indices_t* port_freq_indices);
|
||||
|
||||
void get_csi_rs_params_from_table(const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
|
||||
csi_rs_params_t* table_params);
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,18 @@ nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t leng
|
||||
return (G);
|
||||
}
|
||||
|
||||
uint32_t nr_get_G_SL(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t sci1_dmrs_overlap, uint16_t sci1_re, uint16_t sci1_rb, uint16_t sci2_re, uint16_t csi_rs_re, uint8_t Qm, uint8_t Nl) {
|
||||
|
||||
uint32_t G_SL, slsch_re;
|
||||
slsch_re = ((NR_NB_SC_PER_RB*nb_symb_sch) - (nb_re_dmrs*length_dmrs)) * nb_rb;
|
||||
if (sci1_dmrs_overlap > 0) slsch_re += (nb_re_dmrs * sci1_rb); // return the dmrs that are not transmitted due to SCI1
|
||||
slsch_re -= sci1_re; // REs taken by SCI1
|
||||
slsch_re -= sci2_re; // REs taken by SCI2
|
||||
slsch_re -= csi_rs_re; // REs taken by CSI_RS
|
||||
G_SL = slsch_re * Qm * Nl;
|
||||
return(G_SL);
|
||||
}
|
||||
|
||||
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r)
|
||||
{
|
||||
uint32_t E;
|
||||
|
||||
@@ -35,6 +35,8 @@ uint32_t nr_get_G(uint16_t nb_rb,
|
||||
uint8_t Qm,
|
||||
uint8_t Nl);
|
||||
|
||||
uint32_t nr_get_G_SL(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t sci1_dmrs_overlap, uint16_t sci1_re, uint16_t sci1_rb, uint16_t sci2_re, uint16_t csi_rs_re, uint8_t Qm, uint8_t Nl);
|
||||
|
||||
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
|
||||
|
||||
void compute_nr_prach_seq(uint8_t short_sequence, uint8_t num_sequences, uint8_t rootSequenceIndex, c16_t X_u[64][839]);
|
||||
|
||||
@@ -1496,7 +1496,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
|
||||
// run polar decoder on llrs
|
||||
decoderState =
|
||||
polar_decoder_int16((int16_t *)llrs, decodedPayload, 0, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, nb_bit, pucch_pdu->prb_size);
|
||||
polar_decoder_int16((int16_t *)llrs, decodedPayload, (uint16_t*)NULL, 0, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, nb_bit, pucch_pdu->prb_size);
|
||||
|
||||
// Decoder reversal
|
||||
decodedPayload[0] = reverse_bits(decodedPayload[0], nb_bit);
|
||||
|
||||
331
openair1/PHY/NR_UE_ESTIMATION/nr_sl_channel_estimation.c
Normal file
331
openair1/PHY/NR_UE_ESTIMATION/nr_sl_channel_estimation.c
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_REFSIG/sl_refsig_defs.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
|
||||
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
|
||||
//#define DEBUG_CH
|
||||
//#define DEBUG_PUSCH
|
||||
|
||||
#define NO_INTERP 1
|
||||
#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y)))
|
||||
|
||||
__attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *in1,
|
||||
int *offset1,
|
||||
const int step1,
|
||||
c16_t *in2,
|
||||
int *offset2,
|
||||
const int step2,
|
||||
const int modulo2,
|
||||
const int N) {
|
||||
|
||||
int localOffset1=*offset1;
|
||||
int localOffset2=*offset2;
|
||||
c32_t cumul={0};
|
||||
for (int i=0; i<N; i++) {
|
||||
cumul=c32x16maddShift(in1[localOffset1], in2[localOffset2], cumul, 15);
|
||||
localOffset1+=step1;
|
||||
localOffset2= (localOffset2 + step2) % modulo2;
|
||||
}
|
||||
*offset1=localOffset1;
|
||||
*offset2=localOffset2;
|
||||
return c16x32div(cumul, N);
|
||||
}
|
||||
|
||||
int nr_pssch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int rxFSz,
|
||||
c16_t rxdataF[][rxFSz],
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
int ul_id,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
sl_nr_rx_config_pssch_sci_pdu_t *pssch_pdu,
|
||||
int *max_ch,
|
||||
uint32_t *nvar) {
|
||||
|
||||
c16_t pilot[3280] __attribute__((aligned(32)));
|
||||
const int chest_freq = ue->chest_freq;
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
FILE *debug_ch_est;
|
||||
debug_ch_est = fopen("debug_ch_est.txt","w");
|
||||
#endif
|
||||
NR_gNB_PUSCH *pusch_vars = &ue->pssch_vars[ul_id];
|
||||
c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates;
|
||||
const int symbolSize = ue->SL_UE_PHY_PARAMS.sl_frame_params.ofdm_symbol_size;
|
||||
const int soffset = 0;
|
||||
const int nushift = (p>>1)&1;
|
||||
int ch_offset = symbolSize*symbol;
|
||||
const int symbol_offset = symbolSize*symbol;
|
||||
|
||||
const int k0 = bwp_start_subcarrier;
|
||||
const int nb_rb_pusch = pssch_pdu->subchannel_size*pssch_pdu->l_subch;
|
||||
|
||||
LOG_D(PHY, "In %s: ch_offset %d, soffset %d, symbol_offset %d, OFDM size %d, Ns = %d, k0 = %d, symbol %d\n",
|
||||
__FUNCTION__,
|
||||
ch_offset, soffset,
|
||||
symbol_offset,
|
||||
symbolSize,
|
||||
Ns,
|
||||
k0,
|
||||
symbol);
|
||||
|
||||
//------------------generate DMRS------------------//
|
||||
|
||||
// compute gold sequence based on Nid from SCI1A
|
||||
int nb_re = ue->SL_UE_PHY_PARAMS.sl_frame_params.N_RB_UL*12;
|
||||
uint32_t pssch_dmrs[(nb_re>>5)+1];
|
||||
nr_init_pssch_dmrs_oneshot(&ue->SL_UE_PHY_PARAMS.sl_frame_params,pssch_pdu->Nid,pssch_dmrs,Ns,symbol);
|
||||
float beta_dmrs_pusch = get_beta_dmrs(pssch_pdu->num_layers, pusch_dmrs_type1);
|
||||
int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14);
|
||||
nr_pusch_dmrs_rx(NORMAL, pssch_dmrs, (c16_t *)pilot, (1000+p), 0, nb_rb_pusch,
|
||||
(pssch_pdu->startrb)*NR_NB_SC_PER_RB, 0, dmrs_scaling);
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
|
||||
for (int i = 0; i < (6 * nb_rb_pusch); i++) {
|
||||
LOG_I(PHY, "In %s: %d + j*(%d)\n", __FUNCTION__, pilot[i].r,pilot[i].i);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int nest_count = 0;
|
||||
uint64_t noise_amp2 = 0;
|
||||
c16_t ul_ls_est[symbolSize] __attribute__((aligned(32)));
|
||||
memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize);
|
||||
delay_t delay;
|
||||
memset(&delay, 0, sizeof(delay));
|
||||
NR_DL_FRAME_PARMS *fp = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
int nrx = fp->nb_antennas_rx;
|
||||
c16_t ch_estimates_time[symbolSize] __attribute__((aligned(32)));
|
||||
for (int aarx=0; aarx<nrx; aarx++) {
|
||||
c16_t *rxdataF2 = (c16_t *)&rxdataF[aarx][symbol_offset];
|
||||
c16_t *ul_ch = &ul_ch_estimates[p*nrx+aarx][ch_offset];
|
||||
|
||||
memset(ul_ch,0,sizeof(*ul_ch)*symbolSize);
|
||||
#ifdef DEBUG_PUSCH
|
||||
LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift);
|
||||
LOG_I(PHY, "In %s ch est pilot, N_RB_UL %d\n", __FUNCTION__, fp->N_RB_UL);
|
||||
LOG_I(PHY, "In %s bwp_start_subcarrier %d, k0 %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k0, fp->first_carrier_offset, nb_rb_pusch);
|
||||
LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift);
|
||||
#endif
|
||||
|
||||
if (chest_freq == 0) {
|
||||
c16_t *pil = pilot;
|
||||
int re_offset = k0;
|
||||
LOG_D(PHY,"PSSCH estimation DMRS type 1, Freq-domain interpolation");
|
||||
// For configuration type 1: k = 4*n + 2*k' + delta,
|
||||
// where k' is 0 or 1, and delta is in Table 6.4.1.1.3-1 from TS 38.211
|
||||
int pilot_cnt = 0;
|
||||
int delta = 0; // nr_pusch_dmrs_delta(pusch_dmrs_type1, p);
|
||||
|
||||
for (int n = 0; n < 3 * nb_rb_pusch; n++) {
|
||||
// LS estimation
|
||||
c32_t ch = {0};
|
||||
|
||||
for (int k_line = 0; k_line <= 1; k_line++) {
|
||||
re_offset = (k0 + (n << 2) + (k_line << 1) + delta) % symbolSize;
|
||||
ch = c32x16maddShift(*pil, rxdataF2[soffset + re_offset], ch, 16);
|
||||
pil++;
|
||||
}
|
||||
|
||||
c16_t ch16 = {.r = (int16_t)ch.r, .i = (int16_t)ch.i};
|
||||
*max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i)));
|
||||
for (int k = pilot_cnt << 1; k < (pilot_cnt << 1) + 4; k++) {
|
||||
ul_ls_est[k] = ch16;
|
||||
}
|
||||
pilot_cnt += 2;
|
||||
}
|
||||
|
||||
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t*)ch_estimates_time);
|
||||
|
||||
nr_est_delay(symbolSize, ul_ls_est, ch_estimates_time, &delay);
|
||||
int pusch_delay = delay.est_delay;
|
||||
int delay_idx = get_delay_idx(pusch_delay, MAX_DELAY_COMP);
|
||||
c16_t *ul_delay_table = fp->delay_table[delay_idx];
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
LOG_I(NR_PHY,"Estimated delay = %i\n", pusch_delay >> 1);
|
||||
#endif
|
||||
|
||||
pilot_cnt = 0;
|
||||
for (int n = 0; n < 3*nb_rb_pusch; n++) {
|
||||
|
||||
// Channel interpolation
|
||||
for (int k_line = 0; k_line <= 1; k_line++) {
|
||||
|
||||
// Apply delay
|
||||
int k = pilot_cnt << 1;
|
||||
c16_t ch16 = c16mulShift(ul_ls_est[k], ul_delay_table[k], 8);
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize;
|
||||
c16_t *rxF = &rxdataF2[soffset + re_offset];
|
||||
LOG_I(NR_PHY,"pilot %4d: ul_delay` -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d)\n",
|
||||
pilot_cnt, ul_delay_table[k].r, ul_delay_table[k].i, rxF->r, rxF->i, ch16.r, ch16.i);
|
||||
#endif
|
||||
|
||||
if (pilot_cnt == 0) {
|
||||
c16multaddVectRealComplex(filt16_ul_p0, &ch16, ul_ch, 16);
|
||||
} else if (pilot_cnt == 1 || pilot_cnt == 2) {
|
||||
c16multaddVectRealComplex(filt16_ul_p1p2, &ch16, ul_ch, 16);
|
||||
} else if (pilot_cnt == (6 * nb_rb_pusch - 1)) {
|
||||
c16multaddVectRealComplex(filt16_ul_last, &ch16, ul_ch, 16);
|
||||
} else {
|
||||
c16multaddVectRealComplex(filt16_ul_middle, &ch16, ul_ch, 16);
|
||||
if (pilot_cnt % 2 == 0) {
|
||||
ul_ch += 4;
|
||||
}
|
||||
}
|
||||
|
||||
pilot_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// Revert delay
|
||||
pilot_cnt = 0;
|
||||
ul_ch = &ul_ch_estimates[p * nrx + aarx][ch_offset];
|
||||
int inv_delay_idx = get_delay_idx(-pusch_delay, MAX_DELAY_COMP);
|
||||
c16_t *ul_inv_delay_table = fp->delay_table[inv_delay_idx];
|
||||
for (int n = 0; n < 3 * nb_rb_pusch; n++) {
|
||||
for (int k_line = 0; k_line <= 1; k_line++) {
|
||||
int k = pilot_cnt << 1;
|
||||
ul_ch[k] = c16mulShift(ul_ch[k], ul_inv_delay_table[k], 8);
|
||||
ul_ch[k + 1] = c16mulShift(ul_ch[k + 1], ul_inv_delay_table[k + 1], 8);
|
||||
noise_amp2 += c16amp2(c16sub(ul_ls_est[k], ul_ch[k]));
|
||||
noise_amp2 += c16amp2(c16sub(ul_ls_est[k + 1], ul_ch[k + 1]));
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize;
|
||||
c16_t *rxF = &rxdataF2[soffset + re_offset];
|
||||
LOG_I(NR_PHY,"ch -> (%4d,%4d), ch_inter -> (%4d,%4d)\n", ul_ls_est[k].r, ul_ls_est[k].i, ul_ch[k].r, ul_ch[k].i);
|
||||
#endif
|
||||
pilot_cnt++;
|
||||
nest_count += 2;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // no frequency-domain linear interpolation: average LS channel estimates of 6 DMRS REs per PRB
|
||||
LOG_D(PHY,"PSSCH estimation DMRS type 1, no Freq-domain interpolation\n");
|
||||
c16_t *rxF = &rxdataF2[soffset + nushift];
|
||||
int pil_offset = 0;
|
||||
int re_offset = k0;
|
||||
c16_t ch;
|
||||
|
||||
// First PRB
|
||||
ch=c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6);
|
||||
|
||||
#if NO_INTERP
|
||||
for (c16_t *end=ul_ch+12; ul_ch<end; ul_ch++)
|
||||
*ul_ch=ch;
|
||||
#else
|
||||
c16multaddVectRealComplex(filt8_avlip0, &ch, ul_ch, 8);
|
||||
ul_ch += 8;
|
||||
c16multaddVectRealComplex(filt8_avlip1, &ch, ul_ch, 8);
|
||||
ul_ch += 8;
|
||||
c16multaddVectRealComplex(filt8_avlip2, &ch, ul_ch, 8);
|
||||
ul_ch -= 12;
|
||||
#endif
|
||||
|
||||
for (int pilot_cnt=6; pilot_cnt<6*(nb_rb_pusch-1); pilot_cnt += 6) {
|
||||
ch=c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6);
|
||||
*max_ch = max(*max_ch, max(abs(ch.r), abs(ch.i)));
|
||||
|
||||
#if NO_INTERP
|
||||
for (c16_t *end=ul_ch+12; ul_ch<end; ul_ch++)
|
||||
*ul_ch=ch;
|
||||
#else
|
||||
ul_ch[3].r += (ch.r * 1365)>>15; // 1/12*16384
|
||||
ul_ch[3].i += (ch.i * 1365)>>15; // 1/12*16384
|
||||
|
||||
ul_ch += 4;
|
||||
c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8);
|
||||
ul_ch += 8;
|
||||
c16multaddVectRealComplex(filt8_avlip4, &ch, ul_ch, 8);
|
||||
ul_ch += 8;
|
||||
c16multaddVectRealComplex(filt8_avlip5, &ch, ul_ch, 8);
|
||||
ul_ch -= 8;
|
||||
#endif
|
||||
}
|
||||
// Last PRB
|
||||
ch=c32x16cumulVectVectWithSteps(pilot, &pil_offset, 1, rxF, &re_offset, 2, symbolSize, 6);
|
||||
|
||||
#if NO_INTERP
|
||||
for (c16_t *end=ul_ch+12; ul_ch<end; ul_ch++)
|
||||
*ul_ch=ch;
|
||||
#else
|
||||
ul_ch[3].r += (ch.r * 1365)>>15; // 1/12*16384
|
||||
ul_ch[3].i += (ch.i * 1365)>>15; // 1/12*16384
|
||||
|
||||
ul_ch += 4;
|
||||
c16multaddVectRealComplex(filt8_avlip3, &ch, ul_ch, 8);
|
||||
ul_ch += 8;
|
||||
c16multaddVectRealComplex(filt8_avlip6, &ch, ul_ch, 8);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PUSCH
|
||||
ul_ch = &ul_ch_estimates[p * ue->SL_UE_PHY_PARAMS.sl_frame_params.nb_antennas_rx + aarx][ch_offset];
|
||||
for (int idxP = 0; idxP < ceil((float)nb_rb_pusch * 12 / 8); idxP++) {
|
||||
for (int idxI = 0; idxI < 8; idxI++) {
|
||||
LOG_I(NR_PHY,"%d\t%d\t", ul_ch[idxP * 8 + idxI].r, ul_ch[idxP * 8 + idxI].i);
|
||||
}
|
||||
LOG_I(NR_PHY,"%d\n", idxP);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CH
|
||||
fclose(debug_ch_est);
|
||||
#endif
|
||||
|
||||
if (nvar && nest_count > 0) {
|
||||
*nvar = (uint32_t)(noise_amp2 / nest_count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t calc_power(const int16_t *x, const uint32_t size) {
|
||||
int64_t sum_x = 0;
|
||||
int64_t sum_x2 = 0;
|
||||
for(int k = 0; k<size; k++) {
|
||||
sum_x = sum_x + x[k];
|
||||
sum_x2 = sum_x2 + x[k]*x[k];
|
||||
}
|
||||
|
||||
return sum_x2/size - (sum_x/size)*(sum_x/size);
|
||||
}
|
||||
1139
openair1/PHY/NR_UE_TRANSPORT/csi_sl_rx.c
Normal file
1139
openair1/PHY/NR_UE_TRANSPORT/csi_sl_rx.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -60,7 +60,8 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
|
||||
uint8_t number_of_candidates,
|
||||
uint16_t *CCE,
|
||||
uint8_t *L,
|
||||
int llr_stride_per_symbol)
|
||||
int llr_stride_per_symbol,
|
||||
int pscch_processing)
|
||||
{
|
||||
/*
|
||||
* This function will do demapping and deinterleaving from llr containing demodulated symbols
|
||||
@@ -111,7 +112,7 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
|
||||
int f_bundle_j_list[max_bundles];
|
||||
// for each bundle
|
||||
int c = 0, r = 0, f_bundle_j = 0;
|
||||
for (int nb = 0; nb < max_bundles; nb++) {
|
||||
for (int nb = 0; nb < max_bundles && pscch_processing == 0; nb++) {
|
||||
if (coreset_interleaved == 0)
|
||||
f_bundle_j = nb;
|
||||
else {
|
||||
@@ -127,7 +128,7 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
|
||||
|
||||
// Get cce_list indices by bundle index in ascending order
|
||||
int f_bundle_j_list_ord[number_of_candidates][max_bundles];
|
||||
for (int c_id = 0; c_id < number_of_candidates; c_id++) {
|
||||
for (int c_id = 0; c_id < number_of_candidates && pscch_processing == 0; c_id++) {
|
||||
int start_bund_cand = CCE[c_id] * num_bundles_per_cce;
|
||||
int max_bund_per_cand = L[c_id] * num_bundles_per_cce;
|
||||
int f_bundle_j_list_id = 0;
|
||||
@@ -144,14 +145,19 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb,
|
||||
int rb_count = 0;
|
||||
for (int c_id = 0; c_id < number_of_candidates; c_id++) {
|
||||
for (int symbol_idx = 0; symbol_idx < coreset_time_dur; symbol_idx++) {
|
||||
for (int cce_count = 0; cce_count < L[c_id]; cce_count++) {
|
||||
for (int k = 0; k < NR_NB_REG_PER_CCE / reg_bundle_size_L; k++) { // loop over REG bundles
|
||||
int f = f_bundle_j_list_ord[c_id][k + NR_NB_REG_PER_CCE * cce_count / reg_bundle_size_L];
|
||||
c16_t *in = llr + f * B_rb * RE_PER_RB_OUT_DMRS + symbol_idx * llr_stride_per_symbol;
|
||||
// loop over the RBs of the bundle
|
||||
memcpy(e_rx + RE_PER_RB_OUT_DMRS * rb_count, in, B_rb * RE_PER_RB_OUT_DMRS * sizeof(*e_rx));
|
||||
rb_count += B_rb;
|
||||
}
|
||||
if (pscch_processing == 0) {
|
||||
for (int cce_count = 0; cce_count < L[c_id]; cce_count++) {
|
||||
for (int k = 0; k < NR_NB_REG_PER_CCE / reg_bundle_size_L; k++) { // loop over REG bundles
|
||||
int f = f_bundle_j_list_ord[c_id][k + NR_NB_REG_PER_CCE * cce_count / reg_bundle_size_L];
|
||||
c16_t *in = llr + f * B_rb * RE_PER_RB_OUT_DMRS + symbol_idx * llr_stride_per_symbol;
|
||||
// loop over the RBs of the bundle
|
||||
memcpy(e_rx + RE_PER_RB_OUT_DMRS * rb_count, in, B_rb * RE_PER_RB_OUT_DMRS * sizeof(*e_rx));
|
||||
rb_count += B_rb;
|
||||
}
|
||||
}
|
||||
} // pscch_processing == 0
|
||||
else { //this will need to be changed a bit when we scan for multiple SCI
|
||||
memcpy(e_rx,llr+(RE_PER_RB_OUT_DMRS*coreset_nbr_rb),coreset_nbr_rb*coreset_time_dur*RE_PER_RB_OUT_DMRS*sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,7 +315,8 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
|
||||
nr_phy_data_t *phy_data,
|
||||
int llr_size_symbol,
|
||||
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size],
|
||||
c16_t llr[llr_size_symbol])
|
||||
c16_t llr[llr_size_symbol],
|
||||
int pscch_processing)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
|
||||
@@ -317,7 +324,11 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
|
||||
int32_t pdcch_est_size = ceil_mod(fp->ofdm_symbol_size + LTE_CE_FILTER_LENGTH, 16);
|
||||
__attribute__((aligned(16))) c16_t pdcch_dl_ch_estimates[fp->nb_antennas_rx][pdcch_est_size];
|
||||
int n_rb, cset_start;
|
||||
get_coreset_rballoc(coreset->frequency_domain_resource, &n_rb, &cset_start);
|
||||
if (pscch_processing == 0) get_coreset_rballoc(coreset->frequency_domain_resource,&n_rb,&cset_start);
|
||||
else {
|
||||
cset_start = coreset->frequency_domain_resource[0];
|
||||
n_rb = coreset->frequency_domain_resource[1];
|
||||
}
|
||||
int rb_offset = cset_start + coreset->rb_offset;
|
||||
unsigned short scrambling_id = coreset->pdcch_dmrs_scrambling_id;
|
||||
int dmrs_ref = 0;
|
||||
@@ -351,7 +362,7 @@ static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue,
|
||||
rxdataF_ext,
|
||||
pdcch_dl_ch_estimates_ext,
|
||||
fp,
|
||||
coreset->frequency_domain_resource,
|
||||
pscch_processing ? NULL : coreset->frequency_domain_resource,
|
||||
coreset->rb_offset,
|
||||
n_rb,
|
||||
phy_pdcch_config->pdcch_config[ss_idx].BWPStart);
|
||||
@@ -435,7 +446,8 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue,
|
||||
int num_monitoring_occ,
|
||||
int max_symb,
|
||||
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size],
|
||||
c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol])
|
||||
c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol],
|
||||
int pscch_processing)
|
||||
{
|
||||
const NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
|
||||
|
||||
@@ -459,17 +471,18 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue,
|
||||
phy_data,
|
||||
llr_size_symbol,
|
||||
rxdataF,
|
||||
&pdcch_llr[ss_idx][occ][rel_symb_monOcc * llr_size_symbol]);
|
||||
&pdcch_llr[ss_idx][occ][rel_symb_monOcc * llr_size_symbol],
|
||||
pscch_processing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_pdcch_unscrambling(c16_t *e_rx,
|
||||
uint16_t scrambling_RNTI,
|
||||
uint32_t length,
|
||||
uint16_t pdcch_DMRS_scrambling_id,
|
||||
int16_t *z2)
|
||||
void nr_pdcch_unscrambling(c16_t *e_rx,
|
||||
uint16_t scrambling_RNTI,
|
||||
uint32_t length,
|
||||
uint16_t pdcch_DMRS_scrambling_id,
|
||||
int16_t *z2)
|
||||
{
|
||||
uint32_t rnti = (uint32_t) scrambling_RNTI;
|
||||
uint16_t n_id = pdcch_DMRS_scrambling_id;
|
||||
@@ -487,12 +500,15 @@ static void nr_pdcch_unscrambling(c16_t *e_rx,
|
||||
static void nr_dci_decoding_procedure(const UE_nr_rxtx_proc_t *proc,
|
||||
c16_t *pdcch_e_rx,
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
|
||||
fapi_nr_dci_indication_t *dci_ind)
|
||||
fapi_nr_dci_indication_t *dci_ind,
|
||||
sl_nr_sci_indication_t *sci_ind,
|
||||
int16_t *rsrp_dBm)
|
||||
{
|
||||
int e_rx_cand_idx = 0;
|
||||
// if DCI for SIB we don't break after finding 1st DCI with that RNTI
|
||||
// there might be SIB1 and otherSIB in the same slot with the same length
|
||||
bool is_SI = rel15->rnti == SI_RNTI;
|
||||
AssertFatal(dci_ind == NULL || sci_ind == NULL,"One of dci_ind or sci_ind needs to be NULL\n");
|
||||
|
||||
for (int j = 0; j < rel15->number_of_candidates; j++) {
|
||||
int CCEind = rel15->CCE[j];
|
||||
@@ -505,14 +521,15 @@ static void nr_dci_decoding_procedure(const UE_nr_rxtx_proc_t *proc,
|
||||
// same rnti and size at a different aggregation level
|
||||
int dci_length = rel15->dci_length_options[k];
|
||||
int ind;
|
||||
for (ind = 0; ind < dci_ind->number_of_dcis; ind++) {
|
||||
if (!is_SI && rel15->rnti == dci_ind->dci_list[ind].rnti && dci_length == dci_ind->dci_list[ind].payloadSize) {
|
||||
break;
|
||||
if (dci_ind) {
|
||||
for (ind = 0; ind < dci_ind->number_of_dcis; ind++) {
|
||||
if (!is_SI && rel15->rnti == dci_ind->dci_list[ind].rnti && dci_length == dci_ind->dci_list[ind].payloadSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ind < dci_ind->number_of_dcis)
|
||||
continue;
|
||||
}
|
||||
if (ind < dci_ind->number_of_dcis)
|
||||
continue;
|
||||
|
||||
uint64_t dci_estimation[2] = {0};
|
||||
LOG_D(NR_PHY_DCI,
|
||||
"(%i.%i) Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d, length %d, format %d\n",
|
||||
@@ -529,39 +546,57 @@ static void nr_dci_decoding_procedure(const UE_nr_rxtx_proc_t *proc,
|
||||
int16_t tmp_e[16 * 108];
|
||||
nr_pdcch_unscrambling(&pdcch_e_rx[e_rx_cand_idx],
|
||||
rel15->coreset.scrambling_rnti,
|
||||
L * 108,
|
||||
sci_ind ? L * 18 : L * 108,
|
||||
rel15->coreset.pdcch_dmrs_scrambling_id,
|
||||
tmp_e);
|
||||
|
||||
const uint32_t crc = polar_decoder_int16(tmp_e, dci_estimation, 1, NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
|
||||
uint16_t Nid;
|
||||
const uint32_t crc = polar_decoder_int16(tmp_e, dci_estimation, &Nid, 1, sci_ind ? NR_POLAR_SCI_MESSAGE_TYPE : NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
|
||||
|
||||
rnti_t n_rnti = rel15->rnti;
|
||||
if (crc == n_rnti) {
|
||||
LOG_D(NR_PHY_DCI,
|
||||
"(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
|
||||
"(%i.%i) Received %s indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
|
||||
proc->frame_rx,
|
||||
proc->nr_slot_rx,
|
||||
sci_ind ? "SCI" : "DCI",
|
||||
n_rnti,
|
||||
rel15->dci_format_options[k],
|
||||
CCEind,
|
||||
dci_length,
|
||||
*(unsigned long long *)dci_estimation);
|
||||
AssertFatal(dci_ind->number_of_dcis < sizeofArray(dci_ind->dci_list), "Fix allocation\n");
|
||||
fapi_nr_dci_indication_pdu_t *dci = dci_ind->dci_list + dci_ind->number_of_dcis;
|
||||
*dci = (fapi_nr_dci_indication_pdu_t){
|
||||
.rnti = n_rnti,
|
||||
.n_CCE = CCEind,
|
||||
.N_CCE = L,
|
||||
.dci_format = rel15->dci_format_options[k],
|
||||
.ss_type = rel15->ss_type_options[k],
|
||||
.coreset_type = rel15->coreset.CoreSetType,
|
||||
};
|
||||
int n_rb, cset_start;
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start);
|
||||
dci->cset_start = rel15->BWPStart + cset_start + rel15->coreset.rb_offset;
|
||||
dci->payloadSize = dci_length;
|
||||
memcpy(dci->payloadBits, dci_estimation, (dci_length + 7) / 8);
|
||||
dci_ind->number_of_dcis++;
|
||||
if (dci_ind) {
|
||||
AssertFatal(dci_ind->number_of_dcis < sizeofArray(dci_ind->dci_list), "Fix allocation\n");
|
||||
fapi_nr_dci_indication_pdu_t *dci = dci_ind->dci_list + dci_ind->number_of_dcis;
|
||||
*dci = (fapi_nr_dci_indication_pdu_t){
|
||||
.rnti = n_rnti,
|
||||
.n_CCE = CCEind,
|
||||
.N_CCE = L,
|
||||
.dci_format = rel15->dci_format_options[k],
|
||||
.ss_type = rel15->ss_type_options[k],
|
||||
.coreset_type = rel15->coreset.CoreSetType,
|
||||
};
|
||||
int n_rb, cset_start;
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start);
|
||||
|
||||
dci->cset_start = rel15->BWPStart + cset_start + rel15->coreset.rb_offset;
|
||||
dci->payloadSize = dci_length;
|
||||
memcpy(dci->payloadBits, dci_estimation, (dci_length + 7) / 8);
|
||||
dci_ind->number_of_dcis++;
|
||||
}
|
||||
else {
|
||||
sl_nr_sci_indication_pdu_t *sci = &sci_ind->sci_pdu[sci_ind->number_of_SCIs];
|
||||
*sci = (sl_nr_sci_indication_pdu_t){
|
||||
.sci_format_type = SL_SCI_FORMAT_1A_ON_PSCCH,
|
||||
.subch_index = 0,
|
||||
.pscch_rsrp = *rsrp_dBm,
|
||||
.sci_payloadlen = dci_length,
|
||||
.Nid = Nid
|
||||
};
|
||||
memcpy(sci->sci_payloadBits,&dci_estimation,8);
|
||||
sci_ind->number_of_SCIs++;
|
||||
//ue->SL_UE_PHY_PARAMS.pscch.rx_ok++;
|
||||
}
|
||||
break; // If DCI is found, no need to check for remaining DCI lengths
|
||||
} else {
|
||||
LOG_D(NR_PHY_DCI,
|
||||
@@ -583,12 +618,17 @@ void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
|
||||
int max_monOcc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
nr_phy_data_t *phy_data,
|
||||
c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size])
|
||||
c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size],
|
||||
int sci_indication)
|
||||
{
|
||||
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
|
||||
|
||||
nr_downlink_indication_t dl_indication;
|
||||
nr_sidelink_indication_t sl_indication;
|
||||
|
||||
fapi_nr_dci_indication_t dci_ind = {.SFN = proc->frame_rx, .slot = proc->nr_slot_rx};
|
||||
sl_nr_sci_indication_t sci_ind = {.sfn = proc->frame_rx, .slot = proc->nr_slot_rx};
|
||||
|
||||
|
||||
for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) {
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[ss_idx];
|
||||
@@ -596,8 +636,12 @@ void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
|
||||
const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, ue->frame_parms.symbols_per_slot, unused_start_symb);
|
||||
const int llr_stride = llr_size / rel15->coreset.duration;
|
||||
int n_rb, cset_start;
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start);
|
||||
|
||||
if (!sci_indication) {
|
||||
get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start);
|
||||
} else {
|
||||
n_rb = rel15->coreset.frequency_domain_resource[0];
|
||||
cset_start = rel15->coreset.frequency_domain_resource[1];
|
||||
}
|
||||
for (int m = 0; m < num_monitoring_occ; m++) {
|
||||
/// PDCCH/DCI e-sequence (input to rate matching).
|
||||
c16_t pdcch_e_rx[NR_MAX_PDCCH_SIZE];
|
||||
@@ -612,25 +656,34 @@ void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
|
||||
rel15->number_of_candidates,
|
||||
rel15->CCE,
|
||||
rel15->L,
|
||||
llr_stride);
|
||||
llr_stride,
|
||||
sci_indication);
|
||||
|
||||
nr_dci_decoding_procedure(proc, pdcch_e_rx, rel15, &dci_ind);
|
||||
nr_dci_decoding_procedure(proc, pdcch_e_rx, rel15, sci_indication ? (fapi_nr_dci_indication_t*)NULL : &dci_ind, sci_indication ? &sci_ind : (sl_nr_sci_indication_t*)NULL,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < dci_ind.number_of_dcis; i++) {
|
||||
for (int i = 0; i < (sci_indication? sci_ind.number_of_SCIs : dci_ind.number_of_dcis); i++) {
|
||||
LOG_D(PHY,
|
||||
"Frame.slot: %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
|
||||
"Frame.slot: %d.%d: DCI %i of %d total DCIs found --> %s %x : format %d\n",
|
||||
proc->frame_rx,
|
||||
proc->nr_slot_rx,
|
||||
i + 1,
|
||||
dci_ind.number_of_dcis,
|
||||
dci_ind.dci_list[i].rnti,
|
||||
dci_ind.dci_list[i].dci_format);
|
||||
sci_indication ? sci_ind.number_of_SCIs : dci_ind.number_of_dcis,
|
||||
sci_indication ? "Nid" : "RNTI",
|
||||
sci_indication ? sci_ind.sci_pdu[i].Nid : dci_ind.dci_list[i].rnti,
|
||||
sci_indication ? sci_ind.sci_pdu[i].sci_format_type : dci_ind.dci_list[i].dci_format);
|
||||
}
|
||||
|
||||
/* Send to MAC */
|
||||
nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data);
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
if (sci_indication) {
|
||||
nr_fill_sl_indication(&sl_indication, NULL, &sci_ind, proc, ue, phy_data);
|
||||
ue->if_inst->sl_indication(&sl_indication);
|
||||
}
|
||||
else {
|
||||
nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data);
|
||||
ue->if_inst->dl_indication(&dl_indication);
|
||||
}
|
||||
phy_pdcch_config->nb_search_space = 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -391,6 +391,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
|
||||
uint64_t tmp=0;
|
||||
const uint32_t decoderState = polar_decoder_int16(pbch_e_rx,
|
||||
(uint64_t *)&tmp,
|
||||
(uint16_t*)NULL,
|
||||
0,
|
||||
NR_POLAR_PBCH_MESSAGE_TYPE,
|
||||
NR_POLAR_PBCH_PAYLOAD_BITS,
|
||||
|
||||
@@ -188,6 +188,7 @@ int nr_rx_psbch(PHY_VARS_NR_UE *ue,
|
||||
uint64_t tmp = 0;
|
||||
decoderState = polar_decoder_int16(psbch_e_rx,
|
||||
(uint64_t *)&tmp,
|
||||
(uint16_t*)NULL,
|
||||
0,
|
||||
SL_NR_POLAR_PSBCH_MESSAGE_TYPE,
|
||||
SL_NR_POLAR_PSBCH_PAYLOAD_BITS,
|
||||
|
||||
68
openair1/PHY/NR_UE_TRANSPORT/nr_pscch_tx.c
Normal file
68
openair1/PHY/NR_UE_TRANSPORT/nr_pscch_tx.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_UE_TRANSPORT/nr_pscch_tx.c
|
||||
* \brief Top-level routines for generating and decoding the PSCCH physical channel
|
||||
* \author R. Knopp
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
//#include "PHY/defs.h"
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "PHY/extern.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#include "T.h"
|
||||
|
||||
uint32_t nr_generate_sci1(const PHY_VARS_NR_UE *ue,
|
||||
c16_t *txdataF,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const sl_nr_tx_config_pscch_pssch_pdu_t *pscch_pssch_pdu)
|
||||
{
|
||||
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t pdcch_pdu_rel15={0};
|
||||
// for SCI we put the startRB and number of RBs for PSCCH in the first 2 FAPI FreqDomainResource fields
|
||||
pdcch_pdu_rel15.FreqDomainResource[0] = pscch_pssch_pdu->startrb;
|
||||
pdcch_pdu_rel15.FreqDomainResource[1] = pscch_pssch_pdu->pscch_numrbs;
|
||||
pdcch_pdu_rel15.StartSymbolIndex = 1;
|
||||
pdcch_pdu_rel15.DurationSymbols = pscch_pssch_pdu->pscch_numsym;
|
||||
pdcch_pdu_rel15.numDlDci = 1;
|
||||
pdcch_pdu_rel15.dci_pdu[0].ScramblingId = pscch_pssch_pdu->pscch_dmrs_scrambling_id;
|
||||
pdcch_pdu_rel15.dci_pdu[0].PayloadSizeBits = pscch_pssch_pdu->pscch_sci_payload_len;
|
||||
// for SCI we put the number of PRBs in the FAPI AggregationLevel field
|
||||
pdcch_pdu_rel15.dci_pdu[0].AggregationLevel = pscch_pssch_pdu->pscch_numrbs*pscch_pssch_pdu->pscch_numsym;
|
||||
pdcch_pdu_rel15.dci_pdu[0].ScramblingRNTI = 1010;
|
||||
*(uint64_t*)pdcch_pdu_rel15.dci_pdu[0].Payload = *(uint64_t *)pscch_pssch_pdu->pscch_sci_payload;
|
||||
return(nr_generate_sci((PHY_VARS_NR_UE *)ue,&pdcch_pdu_rel15,(c16_t *)txdataF,amp,(NR_DL_FRAME_PARMS*)frame_parms,nr_slot_tx));
|
||||
}
|
||||
70
openair1/PHY/NR_UE_TRANSPORT/nr_psfch_tx.c
Normal file
70
openair1/PHY/NR_UE_TRANSPORT/nr_psfch_tx.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_UE_TRANSPORT/pucch_nr.c
|
||||
* \brief Top-level routines for generating and decoding the PSFCH physical channel
|
||||
* \author R. Knopp
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email:
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
//#include "PHY/defs.h"
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "PHY/extern.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include <openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h>
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
|
||||
#include "T.h"
|
||||
|
||||
|
||||
void nr_generate_psfch0(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu)
|
||||
{
|
||||
|
||||
fapi_nr_ul_config_pucch_pdu pucch_pdu;
|
||||
|
||||
pucch_pdu.start_symbol_index = psfch_pdu->start_symbol_index;
|
||||
pucch_pdu.hopping_id = psfch_pdu->hopping_id;
|
||||
pucch_pdu.prb_start = psfch_pdu->prb;
|
||||
pucch_pdu.initial_cyclic_shift = psfch_pdu->initial_cyclic_shift;
|
||||
pucch_pdu.mcs = psfch_pdu->mcs;
|
||||
pucch_pdu.nr_of_symbols = psfch_pdu->nr_of_symbols;
|
||||
pucch_pdu.n_bit = psfch_pdu->bit_len_harq;
|
||||
pucch_pdu.bwp_start = psfch_pdu->sl_bwp_start;
|
||||
pucch_pdu.freq_hop_flag = psfch_pdu->freq_hop_flag;
|
||||
pucch_pdu.group_hop_flag = psfch_pdu->group_hop_flag;
|
||||
pucch_pdu.second_hop_prb = psfch_pdu->second_hop_prb;
|
||||
pucch_pdu.sequence_hop_flag = psfch_pdu->sequence_hop_flag;
|
||||
nr_generate_pucch0(txdataF, frame_parms, amp, nr_slot_tx, &pucch_pdu);
|
||||
}
|
||||
220
openair1/PHY/NR_UE_TRANSPORT/nr_sci.c
Normal file
220
openair1/PHY/NR_UE_TRANSPORT/nr_sci.c
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_UE_TRANSPORT/nr_sci.c
|
||||
* \brief Implements SCI encoding and PSCCH TX procedures for sidelink. Based on nr_dci.c.
|
||||
* \author R. Knopp
|
||||
* \date 2023
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
*/
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
//#define DEBUG_PSCCH_DMRS
|
||||
//#define DEBUG_SCI
|
||||
//#define DEBUG_CHANNEL_CODING
|
||||
|
||||
void nr_sci_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint32_t scrambling_RNTI, uint32_t *out,int sci2_flag)
|
||||
{
|
||||
int roundedSz = ((size + 31) / 32);
|
||||
uint32_t *seq = gold_cache(sci2_flag > 0 ? (Nid << 15) + 1010 : (scrambling_RNTI << 15) + Nid, roundedSz);
|
||||
for (int i = 0; i < roundedSz; i++)
|
||||
out[i] = in[i] ^ seq[i];
|
||||
}
|
||||
|
||||
uint32_t nr_generate_sci(PHY_VARS_NR_UE *ue,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot) {
|
||||
|
||||
uint16_t cset_start_sc;
|
||||
uint8_t cset_start_symb, cset_nsymb;
|
||||
int k,l,k_prime,dci_idx, dmrs_idx;
|
||||
|
||||
// compute rb_offset and n_prb based on frequency allocation
|
||||
// for SCI: FreqDomainResource[0] = startRB, FreqDomainResource[1] = numRBs
|
||||
int rb_offset = pdcch_pdu_rel15->FreqDomainResource[0];
|
||||
int n_rb = pdcch_pdu_rel15->FreqDomainResource[1];
|
||||
|
||||
cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
|
||||
c16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(((n_rb+rb_offset+pdcch_pdu_rel15->BWPStart)*6+15)>>5)<<5] __attribute__((aligned(16)));
|
||||
|
||||
uint32_t sci_Nid = 0;
|
||||
|
||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||
/*The coreset is initialised
|
||||
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
|
||||
* or the rb_offset for other coresets
|
||||
* in time: by its first slot and its first symbol*/
|
||||
const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
|
||||
|
||||
uint32_t **gold_pscch_dmrs = ue->nr_gold_pscch_dmrs[slot];
|
||||
|
||||
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
|
||||
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
|
||||
dci_idx = 0;
|
||||
LOG_D(NR_PHY, "pscch: rb_offset %d, nb_rb %d BWP Start %d\n",rb_offset,n_rb,pdcch_pdu_rel15->BWPStart);
|
||||
LOG_D(NR_PHY, "pscch: starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
|
||||
// DMRS length is per OFDM symbol
|
||||
uint32_t dmrs_length = (n_rb+pdcch_pdu_rel15->BWPStart)*6; //2(QPSK)*3(per RB)*6(REG per CCE)
|
||||
uint32_t encoded_length = dci_pdu->AggregationLevel*18; //2(QPSK)*9(per RB) for SCI
|
||||
if (dci_pdu->RNTI != 0xFFFF)
|
||||
LOG_D(PHY, "SCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t SCI encoded length %d (precoder_granularity %d, reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n",
|
||||
rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType,
|
||||
dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits);
|
||||
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
|
||||
|
||||
/// DMRS QPSK modulation
|
||||
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
|
||||
|
||||
nr_modulation(gold_pscch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, (int16_t*)mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
|
||||
|
||||
#ifdef DEBUG_PSCCH_DMRS
|
||||
if(dci_pdu->RNTI!=0xFFFF) {
|
||||
for (int i=0; i<dmrs_length>>1; i++)
|
||||
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
|
||||
&gold_pscch_dmrs[symb][i>>5],gold_pscch_dmrs[symb][i>>5], mod_dmrs[symb][i].r, mod_dmrs[symb][i].i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// SCI payload processing
|
||||
// CRC attachment + Scrambling + Channel coding + Rate matching
|
||||
uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD];
|
||||
|
||||
uint16_t n_RNTI = dci_pdu->RNTI;
|
||||
uint16_t Nid = dci_pdu->ScramblingId;
|
||||
uint16_t scrambling_RNTI = dci_pdu->ScramblingRNTI;
|
||||
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI, 1,
|
||||
NR_POLAR_SCI_MESSAGE_TYPE,
|
||||
dci_pdu->PayloadSizeBits, dci_pdu->AggregationLevel);
|
||||
#ifdef DEBUG_CHANNEL_CODING
|
||||
//debug dump sci
|
||||
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu->AggregationLevel);
|
||||
printf("SCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
|
||||
((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
|
||||
printf("Encoded Payload (length:%u dwords):\n", encoded_length>>5);
|
||||
|
||||
for (int i=0; i<encoded_length>>5; i++)
|
||||
printf("[%d]->0x%08x \t", i,encoder_output[i]);
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
/// Scrambling
|
||||
uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0};
|
||||
nr_sci_scrambling(encoder_output, encoded_length, Nid, scrambling_RNTI, scrambled_output, 0);
|
||||
#ifdef DEBUG_CHANNEL_CODING
|
||||
printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\n \
|
||||
[6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n",
|
||||
scrambled_output[0], scrambled_output[1], scrambled_output[2], scrambled_output[3], scrambled_output[4],scrambled_output[5],
|
||||
scrambled_output[6], scrambled_output[7], scrambled_output[8], scrambled_output[9], scrambled_output[10],scrambled_output[11] );
|
||||
#endif
|
||||
/// QPSK modulation
|
||||
c16_t mod_dci[encoded_length] __attribute__((aligned(16)));
|
||||
nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, (int16_t*)mod_dci); //Qm = 2 as DMRS is QPSK modulated
|
||||
#ifdef DEBUG_SCI
|
||||
|
||||
for (int i=0; i<encoded_length>>1; i++)
|
||||
printf("i %d mod_dci %d %d\n", i, mod_dci[i].r, mod_dci[i].i );
|
||||
|
||||
#endif
|
||||
|
||||
/// Resource mapping
|
||||
|
||||
if (cset_start_sc >= frame_parms->ofdm_symbol_size)
|
||||
cset_start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
int num_regs = dci_pdu->AggregationLevel/pdcch_pdu_rel15->DurationSymbols;
|
||||
|
||||
/*Mapping the encoded SCI along with the DMRS */
|
||||
for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) {
|
||||
// allocating rbs per symbol
|
||||
for (int reg_count = 0; reg_count < num_regs; reg_count++) {
|
||||
if (reg_count == 0) k = cset_start_sc + pdcch_pdu_rel15->dci_pdu[d].CceIndex * NR_NB_SC_PER_RB;
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
l = cset_start_symb + symbol_idx;
|
||||
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
|
||||
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
|
||||
dmrs_idx = reg_count * 3;
|
||||
else
|
||||
dmrs_idx = (pdcch_pdu_rel15->dci_pdu[d].CceIndex + rb_offset + reg_count) * 3;
|
||||
|
||||
k_prime = 0;
|
||||
|
||||
for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
|
||||
if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].r = (amp * mod_dmrs[l][dmrs_idx].r) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].i = (amp * mod_dmrs[l][dmrs_idx].i) >> 15;
|
||||
|
||||
#ifdef DEBUG_PSCCH_DMRS
|
||||
LOG_I(PHY,
|
||||
"PSCCH DMRS %d: l %d position %d => (%d,%d)\n",
|
||||
dmrs_idx,
|
||||
l,
|
||||
k,
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].r,
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].i);
|
||||
#endif
|
||||
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
|
||||
} else { // SCI payload
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].r = (amp * mod_dci[dci_idx].r) >> 15;
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].i = (amp * mod_dci[dci_idx].i) >> 15;
|
||||
#ifdef DEBUG_SCI
|
||||
LOG_I(PHY,
|
||||
"PSCCH: l %d position %d => (%d,%d)\n",
|
||||
l,
|
||||
k,
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].r,
|
||||
txdataF[l * frame_parms->ofdm_symbol_size + k].i);
|
||||
#endif
|
||||
|
||||
dci_idx++;
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
} // m
|
||||
} // reg_count
|
||||
} // symbol_idx
|
||||
|
||||
LOG_D(NR_PHY,
|
||||
"SCI: payloadSize = %d | payload = %llx\n",
|
||||
dci_pdu->PayloadSizeBits,
|
||||
*(unsigned long long *)dci_pdu->Payload);
|
||||
|
||||
sci_Nid = Nid;
|
||||
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
|
||||
return sci_Nid;
|
||||
}
|
||||
85
openair1/PHY/NR_UE_TRANSPORT/nr_slsch.h
Normal file
85
openair1/PHY/NR_UE_TRANSPORT/nr_slsch.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_ulsch.h
|
||||
* \brief functions used for PUSCH/ULSCH physical and transport channels for gNB
|
||||
* \author Ahmed Hussein
|
||||
* \date 2019
|
||||
* \version 0.1
|
||||
* \company Fraunhofer IIS
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL);
|
||||
|
||||
NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
|
||||
|
||||
/*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2
|
||||
@param phy_vars_gNB, Pointer to PHY data structure for gNB
|
||||
@param UE_id, ID of UE transmitting this PUSCH
|
||||
@param ulsch_llr, Pointer to received llr in ulsch
|
||||
@param frame_parms, Pointer to frame descriptor structure
|
||||
@param nb_symb_sch, number of symbols used in the uplink shared channel
|
||||
@param nb_re_dmrs, number of DMRS resource elements in one RB
|
||||
@param nr_tti_rx, current received TTI
|
||||
@param harq_pid, harq process id
|
||||
@param is_crnti
|
||||
*/
|
||||
|
||||
int nr_slsch_decoding(struct PHY_VARS_NR_UE_s *UE,
|
||||
uint8_t UE_id,
|
||||
short *ulsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t harq_pid,
|
||||
uint32_t G,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_t *phy_data,
|
||||
int8_t *ack_nack_rcvd,
|
||||
uint8_t num_acks);
|
||||
|
||||
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
|
||||
@param llr, Pointer to llr bits
|
||||
@param size, length of llr bits
|
||||
@param q, codeword index (0,1)
|
||||
@param Nid, cell id
|
||||
@param n_RNTI, CRNTI
|
||||
*/
|
||||
|
||||
void nr_ulsch_unscrambling(int16_t* llr, uint32_t size, uint32_t Nid, uint32_t n_RNTI);
|
||||
|
||||
void nr_ulsch_layer_demapping(int16_t *llr_cw, uint8_t Nl, uint8_t mod_order, uint32_t length, int16_t **llr_layers);
|
||||
|
||||
NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid);
|
||||
|
||||
void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB);
|
||||
|
||||
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
|
||||
|
||||
NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch);
|
||||
299
openair1/PHY/NR_UE_TRANSPORT/nr_slsch_decoding.c
Normal file
299
openair1/PHY/NR_UE_TRANSPORT/nr_slsch_decoding.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_TRANSPORT/nr_slsch_decoding.c
|
||||
* \brief Top-level routines for decoding LDPC (ULSCH) transport channels from 38.212, V15.4.0 2018-12
|
||||
* \author Ahmed Hussein
|
||||
* \date 2019
|
||||
* \version 0.1
|
||||
* \company Fraunhofer IIS
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
// [from gNB coding]
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/CODING/coding_extern.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/CODING/lte_interleaver_inline.h"
|
||||
#include "PHY/CODING/nrLDPC_extern.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
|
||||
#include "openair1/SCHED_NR_UE/defs.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include <syscall.h>
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
|
||||
//#define DEBUG_ULSCH_DECODING
|
||||
//#define gNB_DEBUG_TRACE
|
||||
|
||||
#define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384
|
||||
//#define DEBUG_CRC
|
||||
#ifdef DEBUG_CRC
|
||||
#define PRINT_CRC_CHECK(a) a
|
||||
#else
|
||||
#define PRINT_CRC_CHECK(a)
|
||||
#endif
|
||||
|
||||
//extern double cpuf;
|
||||
/*
|
||||
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch, uint16_t N_RB_UL)
|
||||
{
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
|
||||
|
||||
if (N_RB_UL != 273) {
|
||||
a_segments = a_segments*N_RB_UL;
|
||||
a_segments = a_segments/273 +1;
|
||||
}
|
||||
|
||||
if (ulsch->harq_process) {
|
||||
if (ulsch->harq_process->b) {
|
||||
free_and_zero(ulsch->harq_process->b);
|
||||
ulsch->harq_process->b = NULL;
|
||||
}
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
free_and_zero(ulsch->harq_process->c[r]);
|
||||
free_and_zero(ulsch->harq_process->d[r]);
|
||||
}
|
||||
free_and_zero(ulsch->harq_process->c);
|
||||
free_and_zero(ulsch->harq_process->d);
|
||||
free_and_zero(ulsch->harq_process->d_to_be_cleared);
|
||||
free_and_zero(ulsch->harq_process);
|
||||
ulsch->harq_process = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL)
|
||||
{
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated
|
||||
|
||||
if (N_RB_UL != 273) {
|
||||
a_segments = a_segments*N_RB_UL;
|
||||
a_segments = a_segments/273 +1;
|
||||
}
|
||||
|
||||
uint32_t ulsch_bytes = a_segments * 1056; // allocated bytes per segment
|
||||
NR_gNB_ULSCH_t ulsch = {0};
|
||||
|
||||
ulsch.max_ldpc_iterations = max_ldpc_iterations;
|
||||
ulsch.harq_pid = -1;
|
||||
ulsch.active = false;
|
||||
|
||||
NR_UL_gNB_HARQ_t *harq = malloc16_clear(sizeof(*harq));
|
||||
init_abort(&harq->abort_decode);
|
||||
ulsch.harq_process = harq;
|
||||
harq->b = malloc16_clear(ulsch_bytes * sizeof(*harq->b));
|
||||
harq->c = malloc16_clear(a_segments * sizeof(*harq->c));
|
||||
harq->d = malloc16_clear(a_segments * sizeof(*harq->d));
|
||||
for (int r = 0; r < a_segments; r++) {
|
||||
harq->c[r] = malloc16_clear(8448 * sizeof(*harq->c[r]));
|
||||
harq->d[r] = malloc16_clear(68 * 384 * sizeof(*harq->d[r]));
|
||||
}
|
||||
harq->d_to_be_cleared = calloc(a_segments, sizeof(bool));
|
||||
AssertFatal(harq->d_to_be_cleared != NULL, "out of memory\n");
|
||||
return(ulsch);
|
||||
}
|
||||
*/
|
||||
int nr_slsch_decoding(struct PHY_VARS_NR_UE_s *UE,
|
||||
uint8_t SLSCH_id,
|
||||
short *slsch_llr,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
nfapi_nr_pusch_pdu_t *pssch_pdu,
|
||||
uint32_t frame,
|
||||
uint8_t nr_tti_rx,
|
||||
uint8_t harq_pid,
|
||||
uint32_t G,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_t *phy_data,
|
||||
int8_t *ack_nack_rcvd,
|
||||
uint8_t num_acks)
|
||||
{
|
||||
nrLDPC_TB_decoding_parameters_t TB;
|
||||
memset(&TB, 0, sizeof(TB));
|
||||
nrLDPC_slot_decoding_parameters_t slot_parameters = {.frame = frame,
|
||||
.slot = nr_tti_rx,
|
||||
.nb_TBs = 1,
|
||||
.threadPool = &get_nrUE_params()->Tpool,
|
||||
.TBs = &TB};
|
||||
|
||||
int max_num_segments = 0;
|
||||
|
||||
NR_gNB_ULSCH_t *slsch = &UE->slsch[SLSCH_id];
|
||||
NR_UL_gNB_HARQ_t *harq_process = slsch->harq_process;
|
||||
|
||||
if (!harq_process) {
|
||||
LOG_E(PHY, "slsch_decoding.c: NULL harq_process pointer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
TB.G = G;
|
||||
|
||||
// The harq_pid is not unique among the active HARQ processes in the instance so we use ULSCH_id instead
|
||||
TB.harq_unique_pid = SLSCH_id;
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
TB.nb_rb = pssch_pdu->rb_size;
|
||||
TB.Qm = pssch_pdu->qam_mod_order;
|
||||
TB.mcs = pssch_pdu->mcs_index;
|
||||
TB.nb_layers = pssch_pdu->nrOfLayers;
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
TB.processedSegments = &harq_process->processedSegments;
|
||||
int TBS = pssch_pdu->pusch_data.tb_size;
|
||||
|
||||
TB.BG = pssch_pdu->maintenance_parms_v3.ldpcBaseGraph;
|
||||
TB.A = TBS << 3;
|
||||
/*
|
||||
NR_gNB_PHY_STATS_t *stats = UE->slsch_stats;
|
||||
if (stats) {
|
||||
stats->frame = frame;
|
||||
stats->ulsch_stats.round_trials[harq_process->round]++;
|
||||
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
stats->ulsch_stats.power[aarx] = dB_fixed_x10(pusch->ulsch_power[aarx]);
|
||||
stats->ulsch_stats.noise_power[aarx] = dB_fixed_x10(pusch->ulsch_noise_power[aarx]);
|
||||
}
|
||||
if (!harq_process->harq_to_be_cleared) {
|
||||
stats->ulsch_stats.current_Qm = TB.Qm;
|
||||
stats->ulsch_stats.current_RI = TB.nb_layers;
|
||||
stats->ulsch_stats.total_bytes_tx += TBS;
|
||||
}
|
||||
}
|
||||
*/
|
||||
LOG_D(PHY,
|
||||
"SLSCH Decoding, harq_pid %d rnti %x TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, Coderate %f RV %d round %d new RX %d\n",
|
||||
harq_pid,
|
||||
slsch->rnti,
|
||||
TB.A,
|
||||
TB.G,
|
||||
TB.mcs,
|
||||
TB.nb_layers,
|
||||
TB.nb_rb,
|
||||
TB.Qm,
|
||||
pssch_pdu->target_code_rate / 10240.0f,
|
||||
pssch_pdu->pusch_data.rv_index,
|
||||
harq_process->round,
|
||||
harq_process->harq_to_be_cleared);
|
||||
|
||||
// [hna] Perform nr_segmenation with input and output set to NULL to calculate only (C, K, Z, F)
|
||||
nr_segmentation(NULL,
|
||||
NULL,
|
||||
lenWithCrc(1, TB.A), // size in case of 1 segment
|
||||
&TB.C,
|
||||
&TB.K,
|
||||
&TB.Z, // [hna] Z is Zc
|
||||
&TB.F,
|
||||
TB.BG);
|
||||
harq_process->C = TB.C;
|
||||
harq_process->K = TB.K;
|
||||
harq_process->Z = TB.Z;
|
||||
harq_process->F = TB.F;
|
||||
|
||||
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * TB.nb_layers; // number of segments to be allocated
|
||||
if (TB.C > a_segments) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, A %d\n", harq_process->C, TB.A);
|
||||
return (-1);
|
||||
}
|
||||
if (TB.nb_rb != 273) {
|
||||
a_segments = a_segments * TB.nb_rb;
|
||||
a_segments = a_segments / 273 + 1;
|
||||
}
|
||||
if (TB.C > a_segments) {
|
||||
LOG_E(PHY, "Illegal harq_process->C %d > %d\n", harq_process->C, a_segments);
|
||||
return -1;
|
||||
}
|
||||
max_num_segments = max(max_num_segments, TB.C);
|
||||
|
||||
#ifdef DEBUG_ULSCH_DECODING
|
||||
printf("slsch decoding nr segmentation Z %d\n", TB.Z);
|
||||
if (!frame % 100)
|
||||
printf("K %d C %d Z %d \n", TB.K, TB.C, TB.Z);
|
||||
printf("Segmentation: C %d, K %d\n", TB.C, TB.K);
|
||||
#endif
|
||||
|
||||
TB.max_ldpc_iterations = slsch->max_ldpc_iterations;
|
||||
TB.rv_index = pssch_pdu->pusch_data.rv_index;
|
||||
TB.tbslbrm = pssch_pdu->maintenance_parms_v3.tbSizeLbrmBytes;
|
||||
TB.abort_decode = &harq_process->abort_decode;
|
||||
set_abort(&harq_process->abort_decode, false);
|
||||
|
||||
nrLDPC_segment_decoding_parameters_t segments[max_num_segments];
|
||||
memset(segments, 0, sizeof(segments));
|
||||
|
||||
TB.segments = segments;
|
||||
|
||||
uint32_t r_offset = 0;
|
||||
for (int r = 0; r < TB.C; r++) {
|
||||
nrLDPC_segment_decoding_parameters_t *segment_parameters = &TB.segments[r];
|
||||
segment_parameters->E = nr_get_E(TB.G, TB.C, TB.Qm, TB.nb_layers, r);
|
||||
segment_parameters->R = nr_get_R_ldpc_decoder(TB.rv_index,
|
||||
segment_parameters->E,
|
||||
TB.BG,
|
||||
TB.Z,
|
||||
&harq_process->llrLen,
|
||||
harq_process->round);
|
||||
segment_parameters->llr = slsch_llr + r_offset;
|
||||
segment_parameters->d = harq_process->d[r];
|
||||
segment_parameters->d_to_be_cleared = &harq_process->d_to_be_cleared[r];
|
||||
segment_parameters->c = harq_process->c[r];
|
||||
segment_parameters->decodeSuccess = false;
|
||||
|
||||
reset_meas(&segment_parameters->ts_deinterleave);
|
||||
reset_meas(&segment_parameters->ts_rate_unmatch);
|
||||
reset_meas(&segment_parameters->ts_ldpc_decode);
|
||||
|
||||
r_offset += segment_parameters->E;
|
||||
}
|
||||
if (harq_process->harq_to_be_cleared) {
|
||||
for (int r = 0; r < TB.C; r++) {
|
||||
harq_process->d_to_be_cleared[r] = true;
|
||||
}
|
||||
harq_process->harq_to_be_cleared = false;
|
||||
}
|
||||
|
||||
int ret_decoder = UE->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
|
||||
// post decode
|
||||
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (int r = 0; r < TB.C; r++) {
|
||||
nrLDPC_segment_decoding_parameters_t nrLDPC_segment_decoding_parameters = TB.segments[r];
|
||||
// Copy c to b in case of decoding success
|
||||
if (nrLDPC_segment_decoding_parameters.decodeSuccess) {
|
||||
memcpy(harq_process->b + offset,
|
||||
harq_process->c[r],
|
||||
(harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
} else {
|
||||
LOG_D(PHY, "sidelink segment error %d/%d\n", r, harq_process->C);
|
||||
LOG_D(PHY, "SLSCH %d in error\n", SLSCH_id);
|
||||
}
|
||||
offset += ((harq_process->K >> 3) - (harq_process->F >> 3) - ((harq_process->C > 1) ? 3 : 0));
|
||||
|
||||
}
|
||||
|
||||
return ret_decoder;
|
||||
}
|
||||
1090
openair1/PHY/NR_UE_TRANSPORT/nr_slsch_demodulation.c
Normal file
1090
openair1/PHY/NR_UE_TRANSPORT/nr_slsch_demodulation.c
Normal file
File diff suppressed because it is too large
Load Diff
548
openair1/PHY/NR_UE_TRANSPORT/nr_slsch_ue.c
Normal file
548
openair1/PHY/NR_UE_TRANSPORT/nr_slsch_ue.c
Normal file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Top-level routines for transmission of the PSSCH TS 38.211 v 16.3.0
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "PHY/gold.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ptrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/sl_refsig_defs.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/MODULATION/nr_modulation.h"
|
||||
#include "PHY/MODULATION/modulation_common.h"
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dci.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "executables/nr-softmodem.h"
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
|
||||
//#define DEBUG_PUSCH_MAPPING
|
||||
//#define DEBUG_MAC_PDU
|
||||
//#define DEBUG_DFT_IDFT
|
||||
|
||||
//extern int32_t uplink_counter;
|
||||
|
||||
void nr_pssch_codeword_scrambling_sci(uint32_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
uint32_t* out)
|
||||
{
|
||||
uint8_t reset, b_idx;
|
||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
||||
|
||||
reset = 1;
|
||||
x2 = (Nid<<15) + 1010;
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
b_idx = i&0x1f;
|
||||
if (b_idx==0) {
|
||||
s = gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
if (i)
|
||||
out++;
|
||||
}
|
||||
*out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<b_idx;
|
||||
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
||||
}
|
||||
}
|
||||
void nr_pssch_codeword_scrambling_sci_2layer(uint32_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
uint32_t* out)
|
||||
{
|
||||
uint8_t reset, b_idx;
|
||||
uint32_t x1 = 0, x2 = 0, s = 0;
|
||||
|
||||
reset = 1;
|
||||
x2 = (Nid<<15) + 1010;
|
||||
|
||||
for (int i=0; i<size; i+=4) {
|
||||
b_idx = i&0x1f;
|
||||
if (b_idx==0) {
|
||||
s = gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
if (i)
|
||||
out++;
|
||||
}
|
||||
*out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<b_idx;
|
||||
*out ^= (((in[i+1])&1) ^ ((s>>(b_idx+1))&1))<<(b_idx+1);
|
||||
*out ^= (((in[i])&1) ^ ((s>>b_idx)&1))<<(b_idx+2);
|
||||
*out ^= (((in[i+1])&1) ^ ((s>>(b_idx+1))&1))<<(b_idx+3);
|
||||
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
||||
}
|
||||
}
|
||||
|
||||
int dmrs_pscch_mask[2] = {7,15} ;
|
||||
|
||||
void nr_ue_slsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const unsigned char harq_pid,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF)
|
||||
{
|
||||
LOG_D(PHY,"nr_ue_ulsch_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
|
||||
|
||||
int Wf[2], Wt[2];
|
||||
int l_prime[2], delta;
|
||||
uint8_t nb_dmrs_re_per_rb;
|
||||
int i;
|
||||
int sample_offsetF, N_RE_prime;
|
||||
|
||||
bool is_csi_rs_slot = false;
|
||||
if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS)
|
||||
is_csi_rs_slot = true;
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = is_csi_rs_slot ? (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)&phy_data->nr_sl_pssch_pscch_pdu.nr_sl_csi_rs_pdu : NULL;
|
||||
if (csi_params)
|
||||
LOG_D(NR_PHY, "Tx start_rb %i, cdm_type %i, csi_type %i, freq_density %i, nr_of_rbs %i, row %i symb_l0 %i is_csi_rs_slot %i\n",
|
||||
csi_params->start_rb, csi_params->cdm_type, csi_params->csi_type, csi_params->freq_density, csi_params->nr_of_rbs, csi_params->row, csi_params->symb_l0, is_csi_rs_slot);
|
||||
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue = &phy_data->ulsch;
|
||||
sl_nr_tx_config_pscch_pssch_pdu_t *pscch_pssch_pdu = &phy_data->nr_sl_pssch_pscch_pdu;
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = &UE->sl_harq_processes[harq_pid];
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = pscch_pssch_pdu == NULL ? &UE->frame_parms : &UE->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
int start_symbol = (1+pscch_pssch_pdu->pssch_startsym);
|
||||
uint16_t ul_dmrs_symb_pos = pscch_pssch_pdu->dmrs_symbol_position;
|
||||
uint8_t number_of_symbols = pscch_pssch_pdu->pssch_numsym;
|
||||
uint8_t dmrs_type = pusch_dmrs_type1;
|
||||
uint16_t start_rb = pscch_pssch_pdu->startrb;
|
||||
uint16_t nb_rb = pscch_pssch_pdu->l_subch * pscch_pssch_pdu->subchannel_size;
|
||||
uint8_t Nl = pscch_pssch_pdu->num_layers;
|
||||
uint8_t mod_order = pscch_pssch_pdu->mod_order;
|
||||
uint16_t rnti = 0;
|
||||
uint8_t cdm_grps_no_data = 1;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
|
||||
uint16_t Tpmi = 0;
|
||||
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
ulsch_ue->Nid_cell = frame_parms->Nid_cell;
|
||||
uint8_t first_dmrs_symbol = 0;
|
||||
bool is_first_dmrs_symbol = true;
|
||||
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
|
||||
if((ul_dmrs_symb_pos >> i) & 0x01) {
|
||||
number_dmrs_symbols += 1;
|
||||
if (is_first_dmrs_symbol) {
|
||||
first_dmrs_symbol = i;
|
||||
is_first_dmrs_symbol = false;
|
||||
}
|
||||
if (csi_params && csi_params->symb_l0 != 0)
|
||||
AssertFatal(i != csi_params->symb_l0, "CSI-RS (symb_l0 %d) MUST not be sent in DMRS symbol (%d)\n", csi_params->symb_l0, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (csi_params && csi_params->symb_l0 != 0)
|
||||
AssertFatal(csi_params->symb_l0 > pscch_pssch_pdu->pscch_numsym, "CSI-RS (symb_l0 %d) MUST not be sent in PSCCH symbol (%d)\n", csi_params->symb_l0, pscch_pssch_pdu->pscch_numsym);
|
||||
nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data;
|
||||
|
||||
//LOG_I(NR_PHY,"%s TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n",pscch_pssch_pdu==NULL?"PUSCH":"PSSCH",
|
||||
// rnti,start_rb,nb_rb,mod_order,Nl,Tpmi,pscch_pssch_pdu==NULL?pusch_pdu->bwp_start:0,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb);
|
||||
// TbD num_of_mod_symbols is set but never used
|
||||
uint16_t num_CSI_REs = is_csi_rs_slot ? get_nRECSI_RS(csi_params->freq_density, csi_params->nr_of_rbs, get_nrUE_params()->nb_antennas_tx) : 0;
|
||||
int num_CSI_REs_per_RB = is_csi_rs_slot ? (num_CSI_REs/csi_params->nr_of_rbs) : 0;
|
||||
N_RE_prime = NR_NB_SC_PER_RB * number_of_symbols - nb_dmrs_re_per_rb * number_dmrs_symbols - N_PRB_oh - num_CSI_REs_per_RB;
|
||||
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb;
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
///////////
|
||||
int sci2_re = get_NREsci2(pscch_pssch_pdu->sci2_alpha_times_100,
|
||||
pscch_pssch_pdu->sci2_payload_len,
|
||||
pscch_pssch_pdu->sci2_beta_offset,
|
||||
pscch_pssch_pdu->pssch_numsym,
|
||||
pscch_pssch_pdu->pscch_numsym,
|
||||
pscch_pssch_pdu->pscch_numrbs,
|
||||
pscch_pssch_pdu->l_subch,
|
||||
pscch_pssch_pdu->subchannel_size,
|
||||
pscch_pssch_pdu->target_coderate);
|
||||
//if (pscch_pssch_pdu) LOG_I(NR_PHY,"dmrs_symbol_position %x, pscch_numsym %d\n",pscch_pssch_pdu->dmrs_symbol_position,pscch_pssch_pdu->pscch_numsym);
|
||||
AssertFatal(pscch_pssch_pdu->pscch_numsym==2 || pscch_pssch_pdu->pscch_numsym==3,"illegal pscch_numsym %d\n",pscch_pssch_pdu->pscch_numsym);
|
||||
int sci1_dmrs_overlap = pscch_pssch_pdu->dmrs_symbol_position & dmrs_pscch_mask[pscch_pssch_pdu->pscch_numsym-2];
|
||||
uint16_t sci1_re = pscch_pssch_pdu->pscch_numsym * pscch_pssch_pdu->pscch_numrbs * NR_NB_SC_PER_RB;
|
||||
unsigned int G = nr_get_G_SL(nb_rb, number_of_symbols, 6, number_dmrs_symbols, sci1_dmrs_overlap, sci1_re, pscch_pssch_pdu->pscch_numrbs, sci2_re, num_CSI_REs, mod_order, Nl);
|
||||
|
||||
// Following code checks, after PSCCH symbols and DMRS symbols, whether PSSCH symbols are used by SCI2 or not,
|
||||
// If true, then CSI-RS MUST not be sent in those PSSCH symbols containing SCI2.
|
||||
if (csi_params && csi_params->symb_l0 != 0) {
|
||||
int32_t next_symbs_sci2_re = 0;
|
||||
int32_t sci1_re = 12 * pscch_pssch_pdu->pscch_numrbs;
|
||||
int32_t non_sci1_re = 12 * nb_rb - sci1_re;
|
||||
next_symbs_sci2_re = first_dmrs_symbol <= pscch_pssch_pdu->pscch_numsym ? sci2_re - (non_sci1_re / 2 - (non_sci1_re * (pscch_pssch_pdu->pscch_numsym - 1)) - (12 * nb_rb) / 2) : sci2_re - (12 * nb_rb) / 2;
|
||||
int8_t remaining_sci2_symb = next_symbs_sci2_re > 0 ? ceil(next_symbs_sci2_re / (12 * nb_rb)) : 0;
|
||||
int8_t non_csi_rs_symbs = pscch_pssch_pdu->pscch_numsym + 1 + remaining_sci2_symb; // 1 is for first dmrs symbol
|
||||
AssertFatal(csi_params->symb_l0 > non_csi_rs_symbs, "CSI-RS MUST not be sent in PSSCH symbol containing SCI2");
|
||||
}
|
||||
|
||||
uint32_t Gsci2 = sci2_re*2*Nl;
|
||||
ws_trace_t tmp = {.nr = true,
|
||||
.direction = DIRECTION_UPLINK,
|
||||
.pdu_buffer = harq_process_ul_ue->payload_AB,
|
||||
.pdu_buffer_size = pscch_pssch_pdu->tb_size,
|
||||
.ueid = 0,
|
||||
.rntiType = WS_C_RNTI,
|
||||
.rnti = rnti,
|
||||
.sysFrame = frame,
|
||||
.subframe = slot,
|
||||
.harq_pid = harq_pid,
|
||||
.oob_event = 0,
|
||||
.oob_event_value = 0};
|
||||
trace_pdu(&tmp);
|
||||
|
||||
uint8_t ULSCH_ids = 0;
|
||||
|
||||
if (nr_ulsch_encoding(UE, ulsch_ue, pscch_pssch_pdu,harq_pid, frame, slot , &G, 1, &ULSCH_ids) == -1)
|
||||
return;
|
||||
|
||||
|
||||
uint32_t sci2_encoded_output[sci2_re*2];
|
||||
|
||||
if (pscch_pssch_pdu) {
|
||||
LOG_D(NR_PHY,"Generating SCI2/PSSCH with %d RE, payload %llx\n",sci2_re,*(unsigned long long*)pscch_pssch_pdu->sci2_payload);
|
||||
// do SCI2 encoding
|
||||
polar_encoder_fast((uint64_t*)pscch_pssch_pdu->sci2_payload, (void*)sci2_encoded_output, 0, 1,
|
||||
NR_POLAR_SCI2_MESSAGE_TYPE,
|
||||
pscch_pssch_pdu->sci2_payload_len, sci2_re);
|
||||
}
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////SLSCH scrambling/////////////////////////
|
||||
///////////
|
||||
|
||||
uint32_t available_bits = G;
|
||||
uint32_t scrambled_output[(available_bits>>5)+1];
|
||||
uint32_t scrambled_output_sci[(Gsci2>>5)+1];
|
||||
memset(scrambled_output, 0, ((available_bits>>5)+1)*sizeof(uint32_t));
|
||||
memset(scrambled_output_sci, 0, ((Gsci2>>5)+1)*sizeof(uint32_t));
|
||||
|
||||
// for (int i=0;i<(Gsci2>>5)+1;i++) LOG_I(NR_PHY,"sci2_encoded[%d] %x\n",i,sci2_encoded_output[i]);
|
||||
// for (int g=0;g<G;g++) LOG_I(NR_PHY,"coded_output_f[%d] %d\n",g,harq_process_ul_ue->f[g]);
|
||||
// LOG_I(NR_PHY,"Scrambling with Nid %x\n",phy_data->pscch_Nid);
|
||||
nr_pusch_codeword_scrambling(harq_process_ul_ue->f,
|
||||
G,
|
||||
phy_data->pscch_Nid,
|
||||
1010,
|
||||
false,
|
||||
NULL,
|
||||
scrambled_output);
|
||||
if (Nl==1)
|
||||
nr_sci_scrambling(sci2_encoded_output,
|
||||
Gsci2,
|
||||
phy_data->pscch_Nid,1010,
|
||||
scrambled_output_sci,1);
|
||||
else
|
||||
nr_pssch_codeword_scrambling_sci_2layer(sci2_encoded_output,
|
||||
Gsci2,
|
||||
phy_data->pscch_Nid,
|
||||
scrambled_output_sci);
|
||||
/////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////ULSCH modulation/////////////////////////
|
||||
///////////
|
||||
|
||||
int max_num_re = Nl*number_of_symbols*nb_rb*NR_NB_SC_PER_RB;
|
||||
int32_t d_mod[max_num_re] __attribute__ ((aligned(16)));
|
||||
|
||||
if (Gsci2 > 0) {
|
||||
nr_modulation(scrambled_output_sci, // assume one codeword for the moment
|
||||
Gsci2,
|
||||
2,
|
||||
(int16_t *)d_mod);
|
||||
//for (int i=0;i<Gsci2;i+=2) LOG_I(NR_PHY,"SCI2 RE %d/%d: (%d,%d)\n",i/2,Gsci2/2,((int16_t*)d_mod)[i],((int16_t*)d_mod)[i+1]);
|
||||
int32_t d_mod2[max_num_re] __attribute__ ((aligned(16)));
|
||||
nr_modulation(scrambled_output, // assume one codeword for the moment
|
||||
available_bits,
|
||||
mod_order,
|
||||
(int16_t *)d_mod2);
|
||||
LOG_D(NR_PHY,"SCI bits %d (sci2_re %d), PSSCH bits %d (PSCCH RE %d), max_re %d\n",Gsci2,sci2_re,available_bits,available_bits/mod_order,max_num_re);
|
||||
memcpy(d_mod+sci2_re,d_mod2,available_bits*sizeof(int32_t)/mod_order);
|
||||
}
|
||||
else
|
||||
nr_modulation(scrambled_output, // assume one codeword for the moment
|
||||
available_bits,
|
||||
mod_order,
|
||||
(int16_t *)d_mod);
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////DMRS Modulation/////////////////////////
|
||||
///////////
|
||||
|
||||
uint16_t n_dmrs = (start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
|
||||
c16_t mod_dmrs[n_dmrs] __attribute((aligned(16)));
|
||||
|
||||
/////////////////////////SLSCH layer mapping/////////////////////////
|
||||
///////////
|
||||
|
||||
c16_t tx_layers[Nl][(available_bits/mod_order)+sci2_re] __attribute__((aligned(64)));
|
||||
nr_ue_layer_mapping((c16_t *)d_mod,
|
||||
Nl,
|
||||
(available_bits/mod_order)+sci2_re,
|
||||
tx_layers);
|
||||
|
||||
///////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////SLSCH RE mapping/////////////////////////
|
||||
///////////
|
||||
|
||||
int encoded_length = frame_parms->N_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl;
|
||||
c16_t tx_precoding[Nl][encoded_length] __attribute__((aligned(64)));
|
||||
|
||||
for (int nl=0; nl < Nl; nl++) {
|
||||
uint8_t k_prime = 0;
|
||||
uint16_t m = 0;
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
LOG_I(NR_PHY,"NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u);
|
||||
#endif
|
||||
|
||||
int dmrs_port = get_dmrs_port(nl,Nl);
|
||||
if (dmrs_port < 0) return;
|
||||
// DMRS params for this dmrs port
|
||||
get_Wt(Wt, dmrs_port, dmrs_type);
|
||||
get_Wf(Wf, dmrs_port, dmrs_type);
|
||||
delta = get_delta(dmrs_port, dmrs_type);
|
||||
|
||||
for (int l=start_symbol; l<start_symbol+number_of_symbols; l++) {
|
||||
|
||||
uint16_t k = start_sc;
|
||||
uint16_t n = 0;
|
||||
uint8_t is_dmrs_sym = 0;
|
||||
uint8_t is_csi_rs_sym = 0;
|
||||
uint16_t dmrs_idx = 0;
|
||||
int16_t csi_rs_rb = 0;
|
||||
int is_pscch_sym = 0;
|
||||
if (l<(start_symbol + pscch_pssch_pdu->pscch_numsym)) {
|
||||
is_pscch_sym = 1;
|
||||
}
|
||||
|
||||
if (is_csi_rs_slot && l == csi_params->symb_l0) {
|
||||
is_csi_rs_sym = 1;
|
||||
csi_rs_rb = csi_params->start_rb;
|
||||
}
|
||||
|
||||
if ((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
is_dmrs_sym = 1;
|
||||
|
||||
|
||||
dmrs_idx = start_rb*6;
|
||||
|
||||
// TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
|
||||
// Perform this on gold sequence, not required when SC FDMA operation is done,
|
||||
LOG_D(PHY,"DMRS in symbol %d\n",l);
|
||||
uint32_t pssch_dmrs[((frame_parms->N_RB_UL * 12) >> 5) + 1];
|
||||
nr_init_pssch_dmrs_oneshot(frame_parms,phy_data->pscch_Nid,pssch_dmrs,slot,l);
|
||||
nr_modulation(pssch_dmrs, n_dmrs*2, DMRS_MOD_ORDER, (int16_t*)mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
|
||||
} else {
|
||||
dmrs_idx = 0;
|
||||
}
|
||||
|
||||
for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) {
|
||||
uint8_t is_dmrs = 0;
|
||||
uint8_t is_csi_rs = 0;
|
||||
|
||||
if (is_pscch_sym && i==(pscch_pssch_pdu->startrb)) {
|
||||
i+=(pscch_pssch_pdu->pscch_numrbs*NR_NB_SC_PER_RB);
|
||||
k+=(pscch_pssch_pdu->pscch_numrbs*NR_NB_SC_PER_RB);
|
||||
if (is_dmrs_sym) {
|
||||
dmrs_idx+=(6*pscch_pssch_pdu->pscch_numrbs);
|
||||
n+=(3*pscch_pssch_pdu->pscch_numrbs);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_PHY, "symbol %d re %d/%d k %d\n", l, i, nb_rb*NR_NB_SC_PER_RB, k);
|
||||
sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
|
||||
|
||||
if (is_dmrs_sym) {
|
||||
if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
|
||||
is_dmrs = 1;
|
||||
}
|
||||
|
||||
if (is_csi_rs_sym) {
|
||||
AssertFatal(1==0,"No SL CSI-RS for now\n");
|
||||
/*
|
||||
if ((k >= csi_params->start_rb * NR_NB_SC_PER_RB) && (i % NR_NB_SC_PER_RB == 0) && (csi_rs_rb < csi_params->nr_of_rbs)) {
|
||||
csi_rs_params_t table_params;
|
||||
get_csi_rs_params_from_table(csi_params, &table_params);
|
||||
port_freq_indices_t *port_freq_indices = (port_freq_indices_t *)malloc(table_params.ports*sizeof(port_freq_indices));
|
||||
get_csi_rs_freq_ind_sl(frame_parms, csi_rs_rb, csi_params, &table_params, port_freq_indices);
|
||||
if (k == port_freq_indices[nl].k) {
|
||||
is_csi_rs = 1;
|
||||
csi_rs_rb++;
|
||||
LOG_D(NR_PHY, "Tx port_freq_indices.p %i, port_freq_indices.k %d, is_csi_rs %d, k = %i, RE %i, csi_rs_rb %i\n",
|
||||
port_freq_indices[nl].p, port_freq_indices[nl].k, is_csi_rs, k, i, csi_rs_rb);
|
||||
}
|
||||
free(port_freq_indices);
|
||||
port_freq_indices = NULL;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (is_dmrs == 1) {
|
||||
tx_precoding[nl][sample_offsetF].r = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx].r) >> 15;
|
||||
tx_precoding[nl][sample_offsetF].i = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx].i) >> 15;
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
LOG_I(NR_PHY,"DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
|
||||
nl, dmrs_idx, l, k, k_prime, n,
|
||||
tx_precoding[nl][sample_offsetF].r,
|
||||
tx_precoding[nl][sample_offsetF].i);
|
||||
#endif
|
||||
|
||||
dmrs_idx++;
|
||||
k_prime++;
|
||||
k_prime&=1;
|
||||
n+=(k_prime)?0:1;
|
||||
|
||||
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) {
|
||||
if (!is_csi_rs) {
|
||||
tx_precoding[nl][sample_offsetF].r = tx_layers[nl][m].r;
|
||||
tx_precoding[nl][sample_offsetF].i = tx_layers[nl][m].i;
|
||||
} else {
|
||||
tx_precoding[nl][sample_offsetF] = (c16_t){.r=0,.i=0};
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PUSCH_MAPPING
|
||||
LOG_I(NR_PHY,"DATA: layer %d\t m %d\t l %d \t k %d \t tx_precoding: %d %d\n",
|
||||
nl, m, l, k,
|
||||
tx_precoding[nl][sample_offsetF].r,
|
||||
tx_precoding[nl][sample_offsetF].i);
|
||||
#endif
|
||||
|
||||
if (!is_csi_rs)
|
||||
m++;
|
||||
|
||||
} else {
|
||||
tx_precoding[nl][sample_offsetF] = (c16_t){.r=0,.i=0};
|
||||
}
|
||||
|
||||
if (++k >= frame_parms->ofdm_symbol_size)
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
} //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++)
|
||||
}//for (l=start_symbol; l<start_symbol+number_of_symbols; l++)
|
||||
}//for (nl=0; nl < Nl; nl++)
|
||||
|
||||
|
||||
|
||||
/////////////////////////ULSCH precoding/////////////////////////
|
||||
///////////
|
||||
///Layer Precoding and Antenna port mapping
|
||||
// tx_layers 0-3 are mapped on antenna ports
|
||||
// The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
|
||||
// The same precoding matrix is applied on prg_size RBs, Thus
|
||||
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
|
||||
// The Precoding matrix:
|
||||
for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
|
||||
for (int l=start_symbol; l<start_symbol+number_of_symbols; l++) {
|
||||
uint16_t k = start_sc;
|
||||
int is_pscch_sym = 0;
|
||||
if (pscch_pssch_pdu && l<(start_symbol + pscch_pssch_pdu->pscch_numsym)) {
|
||||
is_pscch_sym = 1;
|
||||
}
|
||||
|
||||
for (int rb=0; rb<nb_rb; rb++) {
|
||||
if (is_pscch_sym && rb==(pscch_pssch_pdu->startrb)) {
|
||||
k+=(pscch_pssch_pdu->pscch_numrbs*NR_NB_SC_PER_RB);
|
||||
if (k>=frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size;
|
||||
rb=pscch_pssch_pdu->startrb+pscch_pssch_pdu->pscch_numrbs;
|
||||
}
|
||||
//get pmi info
|
||||
uint8_t pmi=Tpmi;
|
||||
|
||||
if (pmi == 0) {//unitary Precoding
|
||||
if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC
|
||||
if (ap<Nl)
|
||||
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
else
|
||||
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
0,
|
||||
NR_NB_SC_PER_RB*sizeof(int32_t));
|
||||
} else { // RB does cross DC
|
||||
int neg_length = frame_parms->ofdm_symbol_size - k;
|
||||
int pos_length = NR_NB_SC_PER_RB - neg_length;
|
||||
if (ap<Nl) {
|
||||
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
|
||||
neg_length*sizeof(int32_t));
|
||||
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
|
||||
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)],
|
||||
pos_length*sizeof(int32_t));
|
||||
} else {
|
||||
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
|
||||
0,
|
||||
neg_length*sizeof(int32_t));
|
||||
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
|
||||
0,
|
||||
pos_length*sizeof(int32_t));
|
||||
}
|
||||
}
|
||||
k += NR_NB_SC_PER_RB;
|
||||
if (k >= frame_parms->ofdm_symbol_size) {
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//get the precoding matrix weights:
|
||||
const char *W_prec;
|
||||
switch (frame_parms->nb_antennas_tx) {
|
||||
case 1://1 antenna port
|
||||
W_prec = nr_W_1l_2p[pmi][ap];
|
||||
break;
|
||||
case 2://2 antenna ports
|
||||
if (Nl == 1)//1 layer
|
||||
W_prec = nr_W_1l_2p[pmi][ap];
|
||||
else//2 layers
|
||||
W_prec = nr_W_2l_2p[pmi][ap];
|
||||
break;
|
||||
case 4://4 antenna ports
|
||||
if (Nl == 1)//1 layer
|
||||
W_prec = nr_W_1l_4p[pmi][ap];
|
||||
else if (Nl == 2)//2 layers
|
||||
W_prec = nr_W_2l_4p[pmi][ap];
|
||||
else if (Nl == 3)//3 layers
|
||||
W_prec = nr_W_3l_4p[pmi][ap];
|
||||
else//4 layers
|
||||
W_prec = nr_W_4l_4p[pmi][ap];
|
||||
break;
|
||||
default:
|
||||
LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
|
||||
W_prec = nr_W_1l_2p[pmi][ap];
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i=0; i<NR_NB_SC_PER_RB; i++) {
|
||||
int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
|
||||
c16_t precodatatx_F = nr_layer_precoder(encoded_length,tx_precoding, W_prec, Nl, re_offset);
|
||||
txdataF[ap][re_offset].r = precodatatx_F.r;
|
||||
txdataF[ap][re_offset].i = precodatatx_F.i;
|
||||
|
||||
if (++k >= frame_parms->ofdm_symbol_size) {
|
||||
k -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //RB loop
|
||||
} // symbol loop
|
||||
}// port loop
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
|
||||
#define NR_PUSCH_y 3 // UCI placeholder bit
|
||||
|
||||
#define FILTER_MARGIN 32
|
||||
|
||||
typedef enum {
|
||||
BIT_TYPE_ULSCH = 0, // Default: UL-SCH data
|
||||
BIT_TYPE_ACK = 1, // HARQ-ACK bit
|
||||
@@ -85,6 +87,8 @@ int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
|
||||
Transport Block.
|
||||
@param[in] phy_vars_ue pointer to ue variables
|
||||
@param[in] ulsch Pointer to ULSCH descriptor
|
||||
@param[in] pscch_pssch_pdu Pointer to PSSCH descriptor. Non-null means PSSCH is used here
|
||||
@param[in] sl_harq_pid Index of harq_pid for PSSCH
|
||||
@param[in] frame frame index
|
||||
@param[in] slot slot index
|
||||
@param[in] G array of Gs
|
||||
@@ -94,6 +98,8 @@ int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
|
||||
*/
|
||||
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
NR_UE_ULSCH_t *ulsch,
|
||||
sl_nr_tx_config_pscch_pssch_pdu_t *pscch_pssch_pdu,
|
||||
uint8_t sl_harq_pid,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
unsigned int *G,
|
||||
@@ -344,6 +350,96 @@ void nr_pbch_unscrambling(int16_t *demod_pbch_e,
|
||||
uint32_t pbch_a_prime,
|
||||
uint32_t *pbch_a_interleaved);
|
||||
void nr_pbch_quantize(int16_t *pbch_llr8, int16_t *pbch_llr, uint16_t len);
|
||||
|
||||
void nr_pdcch_unscrambling(c16_t *e_rx,
|
||||
uint16_t scrambling_RNTI,
|
||||
uint32_t length,
|
||||
uint16_t pdcch_DMRS_scrambling_id,
|
||||
int16_t *z2);
|
||||
|
||||
int nr_pssch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
int rxFSz,
|
||||
c16_t rxdataF[][rxFSz],
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
int ul_id,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
sl_nr_rx_config_pssch_sci_pdu_t *pssch_pdu,
|
||||
int *max_ch,
|
||||
uint32_t *nvar);
|
||||
|
||||
void nr_ue_slsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const unsigned char harq_pid,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
nr_phy_data_tx_t *phy_data,
|
||||
c16_t **txdataF);
|
||||
|
||||
void nr_rx_pssch(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
nr_phy_data_t *phy_data,
|
||||
int rxFSz,
|
||||
c16_t rxdataF[][rxFSz],
|
||||
int16_t *llrs,
|
||||
uint8_t ulsch_id,
|
||||
uint32_t frame,
|
||||
uint8_t slot,
|
||||
unsigned char harq_pid,
|
||||
bool *is_csi_rs_slot);
|
||||
|
||||
void nr_pscch_scrambling(uint32_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
uint32_t scrambling_RNTI,
|
||||
uint32_t *out,
|
||||
int sci_flag);
|
||||
|
||||
void nr_sci_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint32_t scrambling_RNTI, uint32_t *out,int sci2_flag);
|
||||
|
||||
uint32_t nr_generate_sci(PHY_VARS_NR_UE *ue,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
c16_t *txdataF,
|
||||
int16_t amp,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot);
|
||||
|
||||
uint32_t nr_generate_sci1(const PHY_VARS_NR_UE *ue,
|
||||
c16_t *txdataF,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const sl_nr_tx_config_pscch_pssch_pdu_t *pscch_pssch_pdu);
|
||||
|
||||
void nr_generate_psfch0(const PHY_VARS_NR_UE *ue,
|
||||
c16_t **txdataF,
|
||||
const NR_DL_FRAME_PARMS *frame_parms,
|
||||
const int16_t amp,
|
||||
const int nr_slot_tx,
|
||||
const sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu);
|
||||
|
||||
int8_t nr_ue_decode_pucch0(PHY_VARS_NR_UE *ue,
|
||||
int frame,
|
||||
int slot,
|
||||
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP],
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu);
|
||||
|
||||
int8_t nr_ue_decode_psfch0(PHY_VARS_NR_UE *ue,
|
||||
int frame,
|
||||
int slot,
|
||||
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP],
|
||||
const sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu);
|
||||
|
||||
int nr_csi_rs_sinr_estimation(const PHY_VARS_NR_UE *ue,
|
||||
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
|
||||
const uint8_t N_ports,
|
||||
uint8_t mem_offset,
|
||||
const c16_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
|
||||
const uint32_t interference_plus_noise_power,
|
||||
const int16_t log2_re,
|
||||
int32_t *precoded_sinr_dB);
|
||||
|
||||
/**@}*/
|
||||
#endif
|
||||
|
||||
|
||||
@@ -137,6 +137,8 @@ int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
|
||||
|
||||
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
NR_UE_ULSCH_t *ulsch,
|
||||
sl_nr_tx_config_pscch_pssch_pdu_t *pscch_pssch_pdu,
|
||||
uint8_t sl_harq_pid,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
unsigned int *G,
|
||||
@@ -144,6 +146,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
uint8_t *ULSCH_ids)
|
||||
{
|
||||
start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS);
|
||||
AssertFatal(!(pscch_pssch_pdu && nb_ulsch > 1), "pscch_pssch_pdu %p nb_ulsch %d\n", pscch_pssch_pdu, nb_ulsch);
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t TBs[nb_ulsch];
|
||||
memset(TBs, 0, sizeof(TBs));
|
||||
@@ -158,24 +161,27 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
.TBs = TBs};
|
||||
|
||||
int max_num_segments = 0;
|
||||
for (uint_fast8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
|
||||
const uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
const uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
max_num_segments = max(max_num_segments, harq_process->C);
|
||||
}
|
||||
if (!pscch_pssch_pdu) {
|
||||
for (uint_fast8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
|
||||
const uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
const uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
max_num_segments = max(max_num_segments, harq_process->C);
|
||||
}
|
||||
} else
|
||||
max_num_segments = ue->ul_harq_processes[sl_harq_pid].C;
|
||||
|
||||
nrLDPC_segment_encoding_parameters_t segments[nb_ulsch][max_num_segments];
|
||||
memset(segments, 0, sizeof(segments));
|
||||
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
|
||||
uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
uint8_t harq_pid = pscch_pssch_pdu ? sl_harq_pid : ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[pusch_id];
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
NR_UL_UE_HARQ_t *harq_process = pscch_pssch_pdu ? &ue->sl_harq_processes[harq_pid] : &ue->ul_harq_processes[harq_pid];
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch[ULSCH_id].pusch_pdu;
|
||||
const uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
const uint16_t nb_rb = pscch_pssch_pdu ? pscch_pssch_pdu->l_subch * pscch_pssch_pdu->subchannel_size : pusch_pdu->rb_size;
|
||||
TB_parameters->harq_unique_pid = 2 * harq_pid + ULSCH_id;
|
||||
TB_parameters->C = harq_process->C;
|
||||
TB_parameters->K = harq_process->K;
|
||||
@@ -184,13 +190,13 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
TB_parameters->BG = harq_process->BG;
|
||||
TB_parameters->Kb = harq_process->Kb;
|
||||
TB_parameters->nb_rb = nb_rb;
|
||||
TB_parameters->Qm = pusch_pdu->qam_mod_order;
|
||||
TB_parameters->mcs = pusch_pdu->mcs_index;
|
||||
TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
|
||||
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||
TB_parameters->Qm = pscch_pssch_pdu ? pscch_pssch_pdu->mod_order : pusch_pdu->qam_mod_order;
|
||||
TB_parameters->mcs = pscch_pssch_pdu ? pscch_pssch_pdu->mcs : pusch_pdu->mcs_index;
|
||||
TB_parameters->nb_layers = pscch_pssch_pdu ? pscch_pssch_pdu->num_layers : pusch_pdu->nrOfLayers;
|
||||
TB_parameters->rv_index = pscch_pssch_pdu ? pscch_pssch_pdu->rv_index : pusch_pdu->pusch_data.rv_index;
|
||||
TB_parameters->G = G[pusch_id];
|
||||
TB_parameters->tbslbrm = pusch_pdu->tbslbrm;
|
||||
TB_parameters->A = pusch_pdu->pusch_data.tb_size / 8;
|
||||
TB_parameters->tbslbrm = pscch_pssch_pdu ? pscch_pssch_pdu->tbslbrm : pusch_pdu->tbslbrm;
|
||||
TB_parameters->A = pscch_pssch_pdu ? pscch_pssch_pdu->tb_size : pusch_pdu->pusch_data.tb_size / 8;
|
||||
TB_parameters->segments = segments[pusch_id];
|
||||
|
||||
memset(harq_process->f, 0, 14 * nb_rb * 12 * 16);
|
||||
|
||||
@@ -1166,7 +1166,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
rm_info = calc_rate_match_info_uci(pusch_pdu, harq_process_ul_ue, nl_qm, &G[pusch_id]);
|
||||
}
|
||||
|
||||
if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids) == -1) {
|
||||
if (nr_ulsch_encoding(UE, &phy_data->ulsch, NULL, 0, frame, slot, G, 1, ULSCH_ids) == -1) {
|
||||
stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -118,9 +118,14 @@ typedef struct {
|
||||
prs_config_t prs_cfg[NR_MAX_PRS_RESOURCES_PER_SET];
|
||||
} NR_gNB_PRS;
|
||||
|
||||
// forward declaration for sidelink PSSCH PDU pointer in HARQ process
|
||||
struct sl_nr_rx_config_pssch_sci_pdu;
|
||||
|
||||
typedef struct {
|
||||
/// Nfapi ULSCH PDU
|
||||
nfapi_nr_pusch_pdu_t ulsch_pdu; // !!
|
||||
nfapi_nr_pusch_pdu_t ulsch_pdu;
|
||||
/// Sidelink PSSCH PDU pointer (NULL for UL, set for SL reception)
|
||||
struct sl_nr_rx_config_pssch_sci_pdu *pssch_pdu;
|
||||
/// Index of current HARQ round for this DLSCH
|
||||
uint8_t round;
|
||||
bool new_rx;
|
||||
@@ -157,7 +162,7 @@ typedef struct {
|
||||
//////////////////////////////////////////////////////////////
|
||||
} NR_UL_gNB_HARQ_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct NR_gNB_ULSCH_s {
|
||||
uint32_t frame;
|
||||
uint32_t slot;
|
||||
// identifier for concurrent beams
|
||||
@@ -231,7 +236,7 @@ typedef struct {
|
||||
int32_t debugBuff_sample_offset;
|
||||
} NR_gNB_COMMON;
|
||||
|
||||
typedef struct {
|
||||
typedef struct NR_gNB_PUSCH_s {
|
||||
/// \brief Hold the channel estimates in frequency domain based on DRS.
|
||||
/// - first index: rx antenna id [0..nb_antennas_rx[
|
||||
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
|
||||
@@ -319,7 +324,7 @@ typedef struct gNB_L1_proc_t_s {
|
||||
gNB_L1_rxtx_proc_t L1_proc_tx;
|
||||
} gNB_L1_proc_t;
|
||||
|
||||
typedef struct {
|
||||
typedef struct PHY_MEASUREMENTS_gNB_s {
|
||||
// common measurements
|
||||
//! estimated noise power (linear)
|
||||
unsigned int n0_power[MAX_NUM_RU_PER_gNB];
|
||||
|
||||
@@ -74,6 +74,14 @@
|
||||
#include "radio/COMMON/common_lib.h"
|
||||
#include "NR_IF_Module.h"
|
||||
|
||||
#define MAX_PUCCH0_NID 8
|
||||
|
||||
typedef struct {
|
||||
int nb_id;
|
||||
int Nid[MAX_PUCCH0_NID];
|
||||
int lut[MAX_PUCCH0_NID][160][14];
|
||||
} NR_UE_PUCCH0_LUT_t;
|
||||
|
||||
/// Context data structure for gNB subframe processing
|
||||
typedef struct {
|
||||
/// Component Carrier index
|
||||
@@ -202,6 +210,7 @@ typedef struct {
|
||||
#define NR_PSBCH_DMRS_LENGTH 297 // in mod symbols
|
||||
#define NR_PSBCH_DMRS_LENGTH_DWORD 20 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32)
|
||||
#define PBCH_A 24
|
||||
#define NR_SLSCH_RX_MAX 2
|
||||
|
||||
typedef struct {
|
||||
int16_t amp;
|
||||
@@ -267,6 +276,10 @@ typedef struct {
|
||||
int used_by_ue;
|
||||
} nrUE_cell_params_t;
|
||||
|
||||
// forward declarations for PSSCH reusing PUSCH
|
||||
struct NR_gNB_ULSCH_s;
|
||||
struct NR_gNB_PUSCH_s;
|
||||
|
||||
/// Top-level PHY Data Structure for UE
|
||||
typedef struct PHY_VARS_NR_UE_s {
|
||||
/// \brief Module ID indicator for this instance
|
||||
@@ -338,6 +351,7 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
uint8_t prs_active_gNBs;
|
||||
NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_HARQ_PROCESSES];
|
||||
NR_UL_UE_HARQ_t ul_harq_processes[NR_MAX_HARQ_PROCESSES];
|
||||
NR_UL_UE_HARQ_t sl_harq_processes[NR_MAX_HARQ_PROCESSES];
|
||||
|
||||
// Scrambling IDs used in PUSCH DMRS
|
||||
c16_t X_u[64][839];
|
||||
@@ -431,6 +445,21 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
// Sidelink parameters
|
||||
sl_nr_sidelink_mode_t sl_mode;
|
||||
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
|
||||
struct PHY_MEASUREMENTS_gNB_s *sl_measurements;
|
||||
int max_nb_slsch;
|
||||
// we use the gNB ULSCH context for SLSCH reception
|
||||
struct NR_gNB_ULSCH_s *slsch;
|
||||
struct NR_gNB_PUSCH_s *pssch_vars;
|
||||
int pscch_dmrs_gold_init;
|
||||
/// PDCCH DMRS for TX
|
||||
uint32_t ***nr_gold_pscch_dmrs;
|
||||
/// PSCCH DMRS for RX
|
||||
uint32_t ***nr_gold_pscch;
|
||||
/// PSSCH signal detection threshold
|
||||
int pssch_thres;
|
||||
// PUCCH0 Look-up table for cyclic-shifts
|
||||
NR_UE_PUCCH0_LUT_t pucch0_lut;
|
||||
// Threading
|
||||
Actor_t sync_actor;
|
||||
Actor_t *dl_actors;
|
||||
Actor_t *ul_actors;
|
||||
@@ -517,6 +546,8 @@ typedef struct nr_phy_data_tx_s {
|
||||
// Sidelink Rx action decided by MAC
|
||||
sl_nr_tx_config_type_enum_t sl_tx_action;
|
||||
sl_nr_tx_config_psbch_pdu_t psbch_vars;
|
||||
sl_nr_tx_config_pscch_pssch_pdu_t nr_sl_pssch_pscch_pdu;
|
||||
uint32_t pscch_Nid;
|
||||
} nr_phy_data_tx_t;
|
||||
|
||||
typedef struct nr_phy_data_s {
|
||||
@@ -525,6 +556,13 @@ typedef struct nr_phy_data_s {
|
||||
|
||||
// Sidelink Rx action decided by MAC
|
||||
sl_nr_rx_config_type_enum_t sl_rx_action;
|
||||
sl_nr_rx_config_pscch_pdu_t nr_sl_pscch_pdu;
|
||||
sl_nr_rx_config_pssch_sci_pdu_t nr_sl_pssch_sci_pdu;
|
||||
sl_nr_rx_config_pssch_pdu_t nr_sl_pssch_pdu;
|
||||
sl_nr_tti_csi_rs_pdu_t nr_sl_csi_rs_pdu;
|
||||
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu_list;
|
||||
uint8_t num_psfch_pdus;
|
||||
|
||||
NR_UE_CSI_RS csirs_vars;
|
||||
NR_UE_CSI_IM csiim_vars;
|
||||
} nr_phy_data_t;
|
||||
|
||||
@@ -86,6 +86,48 @@ typedef struct SL_NR_SYNC_PARAMS {
|
||||
|
||||
} SL_NR_SYNC_PARAMS_t;
|
||||
|
||||
typedef struct SL_NR_UE_PSSCH {
|
||||
|
||||
// AVG POWER OF PSSCH DMRS in dB/RE
|
||||
int16_t rsrp_dB_per_RE;
|
||||
// AVG POWER OF PSSCH DMRS in dBm/RE
|
||||
int16_t rsrp_dBm_per_RE;
|
||||
|
||||
// STATS - CRC Errors observed during PSSCH reception (per HARQ round)
|
||||
uint32_t rx_errors[8];
|
||||
|
||||
// STATS - CRC Errors observed during PSSCH SCI2 reception
|
||||
uint32_t rx_sci2_errors;
|
||||
|
||||
// STATS - Receptions with CRC OK
|
||||
uint32_t rx_ok;
|
||||
|
||||
// STATS - Receptions with CRC OK
|
||||
uint32_t rx_sci2_ok;
|
||||
|
||||
// STATS - transmissions of PSSCH by the UE
|
||||
uint32_t num_pssch_tx;
|
||||
|
||||
// STATS - transmissions of PSSCH by the UE
|
||||
uint32_t num_pssch_sci2_tx;
|
||||
} SL_NR_UE_PSSCH_t;
|
||||
|
||||
typedef struct SL_NR_UE_PSCCH {
|
||||
|
||||
// AVG POWER OF PSCCH DMRS in dB/RE
|
||||
int16_t rsrp_dB_per_RE;
|
||||
// AVG POWER OF PSCCH DMRS in dBm/RE
|
||||
int16_t rsrp_dBm_per_RE;
|
||||
|
||||
// STATS - Receptions with CRC OK
|
||||
uint32_t rx_ok;
|
||||
|
||||
// STATS - transmissions of PSBCH by the UE
|
||||
uint32_t num_pscch_tx;
|
||||
|
||||
} SL_NR_UE_PSCCH_t;
|
||||
|
||||
|
||||
typedef struct SL_NR_UE_PSBCH {
|
||||
// AVG POWER OF PSBCH DMRS in dB/RE
|
||||
int16_t rsrp_dB_per_RE;
|
||||
@@ -103,6 +145,12 @@ typedef struct SL_NR_UE_PSBCH {
|
||||
|
||||
} SL_NR_UE_PSBCH_t;
|
||||
|
||||
typedef struct SL_NR_UE_PSFCH {
|
||||
// STATS - transmissions of PSFCH by the UE
|
||||
uint32_t num_psfch_tx;
|
||||
uint32_t num_psfch_rx;
|
||||
} SL_NR_UE_PSFCH_t;
|
||||
|
||||
typedef struct sl_nr_ue_phy_params {
|
||||
SL_NR_UE_INIT_PARAMS_t init_params;
|
||||
|
||||
@@ -111,6 +159,15 @@ typedef struct sl_nr_ue_phy_params {
|
||||
// Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn
|
||||
SL_NR_UE_PSBCH_t psbch;
|
||||
|
||||
// sidelink phy parameters used for pscch reception/txn
|
||||
SL_NR_UE_PSCCH_t pscch;
|
||||
|
||||
// sidelink phy parameters used for pssch reception/txn
|
||||
SL_NR_UE_PSSCH_t pssch;
|
||||
|
||||
// sidelink phy parameters used for psfch reception/txn
|
||||
SL_NR_UE_PSFCH_t psfch;
|
||||
|
||||
// Configuration parameters from MAC
|
||||
sl_nr_phy_config_request_t sl_config;
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef __openair_GOLD_H__
|
||||
#define __openair_GOLD_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset)
|
||||
{
|
||||
int32_t n;
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp);
|
||||
|
||||
int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data,int pscch_processing);
|
||||
|
||||
void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
|
||||
@@ -117,14 +117,16 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue,
|
||||
int num_monitoring_occ,
|
||||
int max_symb,
|
||||
c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size],
|
||||
c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol]);
|
||||
c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol],
|
||||
int pscch_processing);
|
||||
|
||||
void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc,
|
||||
int llr_size,
|
||||
int max_monOcc,
|
||||
PHY_VARS_NR_UE *ue,
|
||||
nr_phy_data_t *phy_data,
|
||||
c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size]);
|
||||
c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size],
|
||||
int sci_indication);
|
||||
|
||||
void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue,
|
||||
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
@@ -135,7 +137,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu);
|
||||
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
int psbch_pscch_pssch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data);
|
||||
void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp);
|
||||
/*! \brief This function prepares the sl indication to pass to the MAC
|
||||
*/
|
||||
@@ -152,5 +154,12 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
void *typeSpecific,
|
||||
uint16_t rx_slss_id);
|
||||
|
||||
typedef struct {
|
||||
uint8_t *b;
|
||||
int TBS;
|
||||
int harq_pid;
|
||||
bool rxok;
|
||||
} slsch_status_t;
|
||||
|
||||
#endif
|
||||
/** @}*/
|
||||
|
||||
@@ -1011,7 +1011,7 @@ static int get_max_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config)
|
||||
return max_pdcch_symb;
|
||||
}
|
||||
|
||||
void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data, int pscch_processing)
|
||||
{
|
||||
NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
|
||||
if (phy_pdcch_config->nb_search_space == 0)
|
||||
@@ -1019,7 +1019,7 @@ void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
|
||||
TracyCZone(ctx, true);
|
||||
/* process PDCCH */
|
||||
LOG_D(PHY, " ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", proc->frame_rx % 1024, proc->nr_slot_rx);
|
||||
LOG_D(PHY, " ------ --> %s ChannelComp/LLR Frame.slot %d.%d ------ \n", pscch_processing ? "PSCCH" : "PDCCH", proc->frame_rx % 1024, proc->nr_slot_rx);
|
||||
start_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS);
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
int num_monitoring_occ = get_max_pdcch_monOcc(phy_pdcch_config, fp->symbols_per_slot);
|
||||
@@ -1042,9 +1042,9 @@ void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
for (int ant = 0; ant < fp->nb_antennas_rx; ant++)
|
||||
memcpy(rxdataF_symb[ant], &rxdataF[ant][symbol * fp->ofdm_symbol_size], sizeof(c16_t) * fp->ofdm_symbol_size);
|
||||
|
||||
nr_pdcch_generate_llr(ue, proc, symbol, phy_data, llr_size_symbol, num_monitoring_occ, max_nb_symb_pdcch, rxdataF_symb, pdcch_llr);
|
||||
nr_pdcch_generate_llr(ue, proc, symbol, phy_data, llr_size_symbol, num_monitoring_occ, max_nb_symb_pdcch, rxdataF_symb, pdcch_llr,pscch_processing);
|
||||
if (symbol == last_symb_pdcch) {
|
||||
nr_pdcch_dci_indication(proc, llr_size_symbol * max_nb_symb_pdcch, num_monitoring_occ, ue, phy_data, pdcch_llr);
|
||||
nr_pdcch_dci_indication(proc, llr_size_symbol * max_nb_symb_pdcch, num_monitoring_occ, ue, phy_data, pdcch_llr,pscch_processing);
|
||||
UEscopeCopy(ue, pdcchLlr, pdcch_llr, sizeof(c16_t), 1, sizeof(pdcch_llr) / sizeof(c16_t), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "PHY/MODULATION/modulation_UE.h"
|
||||
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_slsch.h"
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
|
||||
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
|
||||
sl_nr_rx_indication_t *rx_ind,
|
||||
@@ -60,6 +62,19 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
|
||||
|
||||
switch (pdu_type) {
|
||||
case SL_NR_RX_PDU_TYPE_SLSCH:
|
||||
case SL_NR_RX_PDU_TYPE_SLSCH_PSFCH: {
|
||||
sl_nr_slsch_pdu_t *rx_slsch_pdu = &rx_ind->rx_indication_body[n_pdus - 1].rx_slsch_pdu;
|
||||
slsch_status_t *slsch_status = (slsch_status_t *)typeSpecific;
|
||||
rx_slsch_pdu->pdu = slsch_status->b;
|
||||
rx_slsch_pdu->pdu_length = slsch_status->TBS;
|
||||
rx_slsch_pdu->harq_pid = slsch_status->harq_pid;
|
||||
rx_slsch_pdu->ack_nack = (slsch_status->rxok==true) ? 1 : 0;
|
||||
|
||||
LOG_D(NR_MAC, "%4d.%2d Received %s SLSCH\n", rx_ind->sfn, rx_ind->slot, rx_slsch_pdu->ack_nack ? "Correct" : "Incorrect");
|
||||
if (slsch_status->rxok==true) ue->SL_UE_PHY_PARAMS.pssch.rx_ok++;
|
||||
else ue->SL_UE_PHY_PARAMS.pssch.rx_errors[0]++;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case FAPI_NR_RX_PDU_TYPE_SSB: {
|
||||
sl_nr_ssb_pdu_t *ssb_pdu = &rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu;
|
||||
@@ -92,6 +107,7 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
struct complex16 dl_ch_estimates[][estimateSz],
|
||||
nr_phy_data_t *phy_data,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP])
|
||||
|
||||
{
|
||||
int ret = 0;
|
||||
DevAssert(ue);
|
||||
@@ -147,21 +163,190 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
|
||||
extern int dmrs_pscch_mask[2];
|
||||
int nr_slsch_procedures(PHY_VARS_NR_UE *ue, int frame_rx, int slot_rx, int SLSCH_id, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data, bool is_csi_rs_slot, int8_t *ack_nack_rcvd, int num_acks) {
|
||||
|
||||
|
||||
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
|
||||
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
|
||||
sl_nr_rx_config_pssch_pdu_t *slsch_pdu = &phy_data->nr_sl_pssch_pdu; //ue->slsch[SLSCH_id].harq_process->slsch_pdu;
|
||||
sl_nr_rx_config_pssch_sci_pdu_t *pssch_pdu = &phy_data->nr_sl_pssch_sci_pdu; //ue->slsch[SLSCH_id].harq_process->pssch_pdu;
|
||||
|
||||
uint8_t freq_density = 0;
|
||||
uint8_t nr_of_rbs = 0;
|
||||
if (is_csi_rs_slot) {
|
||||
AssertFatal(1==0,"Don't do SL CSI-RS for now\n");
|
||||
/*
|
||||
freq_density = ue->csirs_vars[0]->csirs_config_pdu.freq_density;
|
||||
nr_of_rbs = ue->csirs_vars[0]->csirs_config_pdu.nr_of_rbs;
|
||||
AssertFatal((freq_density == 1) || (nr_of_rbs > 0), "CSI-RS parameters are not properly configured\n");
|
||||
*/
|
||||
}
|
||||
int harq_pid = slsch_pdu->harq_pid;
|
||||
uint16_t nb_re_dmrs;
|
||||
uint16_t start_symbol = 1;
|
||||
uint16_t number_symbols = pssch_pdu->pssch_numsym;
|
||||
ue->slsch[SLSCH_id].harq_process->harq_to_be_cleared=true;
|
||||
uint8_t number_dmrs_symbols = 0;
|
||||
for (int l = start_symbol; l < start_symbol + number_symbols; l++)
|
||||
number_dmrs_symbols += ((pssch_pdu->dmrs_symbol_position)>>l)&0x01;
|
||||
|
||||
nb_re_dmrs = 6;
|
||||
|
||||
uint32_t rb_size = pssch_pdu->num_subch*pssch_pdu->subchannel_size;
|
||||
int sci1_dmrs_overlap = pssch_pdu->dmrs_symbol_position & dmrs_pscch_mask[pssch_pdu->pscch_numsym-2];
|
||||
int sci2_re = get_NREsci2(pssch_pdu->sci2_alpha_times_100,
|
||||
pssch_pdu->sci2_len,
|
||||
pssch_pdu->sci2_beta_offset,
|
||||
pssch_pdu->pssch_numsym,
|
||||
pssch_pdu->pscch_numsym,
|
||||
pssch_pdu->pscch_numrbs,
|
||||
pssch_pdu->l_subch,
|
||||
pssch_pdu->subchannel_size,
|
||||
pssch_pdu->targetCodeRate);
|
||||
|
||||
uint8_t nr_rbs_w_csi_rs = nr_of_rbs / freq_density;
|
||||
uint8_t subcarriers_used = get_nrUE_params()->nb_antennas_tx > 2 ? 2 : get_nrUE_params()->nb_antennas_tx;
|
||||
int num_CSI_REs = is_csi_rs_slot ? nr_rbs_w_csi_rs * subcarriers_used : 0;
|
||||
uint16_t sci1_re = pssch_pdu->pscch_numsym * pssch_pdu->pscch_numrbs * NR_NB_SC_PER_RB;
|
||||
uint32_t G = nr_get_G_SL(rb_size,
|
||||
number_symbols,
|
||||
nb_re_dmrs,
|
||||
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
|
||||
sci1_dmrs_overlap,
|
||||
sci1_re,
|
||||
pssch_pdu->pscch_numrbs,
|
||||
sci2_re,
|
||||
num_CSI_REs,
|
||||
pssch_pdu->mod_order,
|
||||
pssch_pdu->num_layers);
|
||||
|
||||
AssertFatal(G>0,"G is 0 : rb_size %u, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %u, nrOfLayer %u\n",
|
||||
rb_size,
|
||||
number_symbols,
|
||||
nb_re_dmrs,
|
||||
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
|
||||
pssch_pdu->mod_order,
|
||||
pssch_pdu->num_layers);
|
||||
LOG_D(NR_PHY,"slot %d rb_size %d, number_symbols %d, nb_re_dmrs %d, dmrs symbol positions %d, number_dmrs_symbols %d, qam_mod_order %d, nrOfLayer %d\n",
|
||||
slot_rx,
|
||||
rb_size,
|
||||
number_symbols,
|
||||
nb_re_dmrs,
|
||||
pssch_pdu->dmrs_symbol_position,
|
||||
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
|
||||
pssch_pdu->mod_order,
|
||||
pssch_pdu->num_layers);
|
||||
|
||||
//----------------------------------------------------------
|
||||
//--------------------- SLSCH decoding ---------------------
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
nfapi_nr_pusch_pdu_t pusch_pdu;
|
||||
|
||||
pusch_pdu.rb_size = rb_size;
|
||||
pusch_pdu.qam_mod_order = pssch_pdu->mod_order;
|
||||
pusch_pdu.mcs_index = slsch_pdu->mcs;
|
||||
pusch_pdu.nrOfLayers = pssch_pdu->num_layers;
|
||||
pusch_pdu.pusch_data.tb_size=slsch_pdu->tb_size;
|
||||
uint32_t A = slsch_pdu->tb_size<<3;
|
||||
pusch_pdu.target_code_rate=slsch_pdu->target_coderate;
|
||||
float Coderate = (float) (slsch_pdu->target_coderate) / 10240.0f;
|
||||
pusch_pdu.pusch_data.rv_index=slsch_pdu->rv_index;
|
||||
|
||||
if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){
|
||||
pusch_pdu.maintenance_parms_v3.ldpcBaseGraph=2;
|
||||
}
|
||||
else{
|
||||
pusch_pdu.maintenance_parms_v3.ldpcBaseGraph=1;
|
||||
}
|
||||
pusch_pdu.maintenance_parms_v3.tbSizeLbrmBytes=slsch_pdu->tbslbrm>>3;
|
||||
|
||||
LOG_D(NR_PHY, "%4d.%2d Calling nr_slsch_decoding\n", frame_rx, slot_rx);
|
||||
int nbDecode =
|
||||
nr_slsch_decoding(ue, SLSCH_id, ue->pssch_vars[SLSCH_id].llr, fp, &pusch_pdu, frame_rx, slot_rx, harq_pid, G, proc, phy_data, ack_nack_rcvd, num_acks);
|
||||
|
||||
|
||||
sl_nr_rx_indication_t sl_rx_indication;
|
||||
nr_sidelink_indication_t sl_indication;
|
||||
slsch_status_t slsch_status;
|
||||
ue->slsch[SLSCH_id].active = false;
|
||||
NR_UL_gNB_HARQ_t *harq_process = &ue->slsch[SLSCH_id].harq_process[harq_pid];
|
||||
slsch_status.b = harq_process->b;
|
||||
slsch_status.TBS = slsch_pdu->tb_size;
|
||||
slsch_status.harq_pid = harq_pid;
|
||||
slsch_status.rxok = nbDecode>0 ? true : false;
|
||||
LOG_D(NR_PHY, "%4d.%2d SLSCH %s received ok \n", proc->frame_rx, proc->nr_slot_rx,nbDecode>0 ? "" : "not");
|
||||
sl_rx_indication.sfn = proc->frame_rx;
|
||||
sl_rx_indication.slot = proc->nr_slot_rx;
|
||||
sl_rx_indication.rx_indication_body[0].rx_slsch_pdu.ack_nack_rcvd = (uint8_t*)calloc(num_acks, sizeof(uint8_t));
|
||||
memcpy((void*)sl_rx_indication.rx_indication_body[0].rx_slsch_pdu.ack_nack_rcvd, (void*)ack_nack_rcvd,
|
||||
num_acks * sizeof(uint8_t));
|
||||
sl_rx_indication.rx_indication_body[0].rx_slsch_pdu.num_acks_rcvd = num_acks;
|
||||
uint8_t pdu_type = phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_PSFCH ? SL_NR_RX_PDU_TYPE_SLSCH_PSFCH : SL_NR_RX_PDU_TYPE_SLSCH;
|
||||
|
||||
nr_fill_sl_rx_indication(&sl_rx_indication, pdu_type, ue, 1, (void*)&slsch_status, 0);
|
||||
nr_fill_sl_indication(&sl_indication,&sl_rx_indication,NULL,proc,ue,phy_data);
|
||||
if (ue->if_inst && ue->if_inst->sl_indication)
|
||||
ue->if_inst->sl_indication(&sl_indication);
|
||||
|
||||
return nbDecode;
|
||||
}
|
||||
|
||||
int psbch_pscch_pssch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
|
||||
{
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_slot_rx = proc->nr_slot_rx;
|
||||
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
|
||||
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
|
||||
bool is_csi_rs_slot = false;
|
||||
int8_t *ack_nack_rcvd = NULL;
|
||||
|
||||
int sampleShift = INT_MAX;
|
||||
|
||||
start_meas(&sl_phy_params->phy_proc_sl_rx);
|
||||
|
||||
|
||||
LOG_D(NR_PHY, " ****** Sidelink RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx % 1024, nr_slot_rx);
|
||||
|
||||
const uint32_t rxdataF_sz = fp->samples_per_slot_wCP;
|
||||
__attribute__((aligned(32))) c16_t rxdataF[fp->nb_antennas_rx][rxdataF_sz];
|
||||
|
||||
if ((frame_rx&127) == 0) {
|
||||
LOG_I(NR_PHY,"============================================\n");
|
||||
|
||||
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSBCH Stats: TX %u, RX ok %u, RX not ok %u\n",KGRN,
|
||||
ue->Mod_id, frame_rx, nr_slot_rx,
|
||||
sl_phy_params->psbch.num_psbch_tx,
|
||||
sl_phy_params->psbch.rx_ok,
|
||||
sl_phy_params->psbch.rx_errors);
|
||||
|
||||
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSCCH Stats: TX %u, RX ok %u\n",KGRN,
|
||||
ue->Mod_id, frame_rx, nr_slot_rx,
|
||||
sl_phy_params->pscch.num_pscch_tx,
|
||||
sl_phy_params->pscch.rx_ok);
|
||||
|
||||
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSSCH/SCI2 Stats: TX %u, RX ok %u, RX not ok %u\n",KGRN,
|
||||
ue->Mod_id, frame_rx, nr_slot_rx,
|
||||
sl_phy_params->pssch.num_pssch_sci2_tx,
|
||||
sl_phy_params->pssch.rx_sci2_ok,
|
||||
sl_phy_params->pssch.rx_sci2_errors);
|
||||
LOG_I(NR_PHY,"%s[UE%d] %d:%d PSSCH Stats: TX %u, RX ok %u, RX not ok (%u/%u/%u/%u)\n",KGRN,
|
||||
ue->Mod_id, frame_rx, nr_slot_rx,
|
||||
sl_phy_params->pssch.num_pssch_tx,
|
||||
sl_phy_params->pssch.rx_ok,
|
||||
sl_phy_params->pssch.rx_errors[0],
|
||||
sl_phy_params->pssch.rx_errors[1],
|
||||
sl_phy_params->pssch.rx_errors[2],
|
||||
sl_phy_params->pssch.rx_errors[3]);
|
||||
LOG_I(NR_PHY, "%s[UE%d] %d:%d PSFCH Stats: TX %u\n", KGRN,
|
||||
ue->Mod_id, frame_rx, nr_slot_rx,
|
||||
sl_phy_params->psfch.num_psfch_tx
|
||||
);
|
||||
LOG_I(NR_PHY,"============================================\n");
|
||||
}
|
||||
|
||||
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH) {
|
||||
const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size;
|
||||
|
||||
@@ -204,7 +389,6 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
// PSBCH present in symbols 0, 5-12 for normal cp
|
||||
sym = (sym == 0) ? 5 : sym + 1;
|
||||
}
|
||||
|
||||
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(ue, sl_phy_params, fp, rxdataF, false);
|
||||
|
||||
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
|
||||
@@ -235,7 +419,188 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
|
||||
LOG_I(NR_PHY, "============================================\n");
|
||||
}
|
||||
}
|
||||
else if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSCCH){
|
||||
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_data->phy_pdcch_config.pdcch_config[0];
|
||||
LOG_D(NR_PHY,"pscch_numsym = %d\n",phy_data->nr_sl_pscch_pdu.pscch_numsym);
|
||||
LOG_D(NR_PHY,"pscch_startrb = %d\n",phy_data->nr_sl_pscch_pdu.pscch_startrb);
|
||||
LOG_D(NR_PHY,"pscch_numrbs = %d\n",phy_data->nr_sl_pscch_pdu.pscch_numrbs);
|
||||
LOG_D(NR_PHY,"pscch_dmrs_scrambling_id = %d\n",phy_data->nr_sl_pscch_pdu.pscch_dmrs_scrambling_id);
|
||||
|
||||
LOG_D(NR_PHY,"pscch_num_subch= %d\n",phy_data->nr_sl_pscch_pdu.num_subch);
|
||||
LOG_D(NR_PHY,"pscch_subchannel_size = %d\n",phy_data->nr_sl_pscch_pdu.subchannel_size);
|
||||
LOG_D(NR_PHY,"pscch_l_subch = %d\n",phy_data->nr_sl_pscch_pdu.l_subch);
|
||||
LOG_D(NR_PHY,"pscch_pssch_numsym = %d\n",phy_data->nr_sl_pscch_pdu.pssch_numsym);
|
||||
LOG_D(NR_PHY,"sense_pscch = %d\n",phy_data->nr_sl_pscch_pdu.sense_pscch);
|
||||
|
||||
rel15->rnti = 0;
|
||||
rel15->BWPSize = phy_data->nr_sl_pscch_pdu.num_subch * phy_data->nr_sl_pscch_pdu.subchannel_size;
|
||||
rel15->BWPStart = phy_data->nr_sl_pscch_pdu.pscch_startrb;
|
||||
rel15->SubcarrierSpacing = fp->subcarrier_spacing;
|
||||
rel15->coreset.frequency_domain_resource[0] = phy_data->nr_sl_pscch_pdu.pscch_startrb;
|
||||
rel15->coreset.frequency_domain_resource[1] = phy_data->nr_sl_pscch_pdu.pscch_numrbs;
|
||||
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
|
||||
rel15->coreset.StartSymbolIndex = 1;
|
||||
rel15->coreset.RegBundleSize = 0;
|
||||
rel15->coreset.duration = phy_data->nr_sl_pscch_pdu.pscch_numsym;
|
||||
rel15->coreset.pdcch_dmrs_scrambling_id = phy_data->nr_sl_pscch_pdu.pscch_dmrs_scrambling_id;
|
||||
rel15->coreset.scrambling_rnti = 1010;
|
||||
rel15->coreset.tci_present_in_dci = 0;
|
||||
|
||||
rel15->number_of_candidates = phy_data->nr_sl_pscch_pdu.l_subch;
|
||||
rel15->num_dci_options = 1;
|
||||
rel15->dci_length_options[0] = phy_data->nr_sl_pscch_pdu.sci_1a_length;
|
||||
// L now provides the number of PRBs used by PSCCH instead of the number of CCEs
|
||||
rel15->L[0] = phy_data->nr_sl_pscch_pdu.pscch_numrbs * phy_data->nr_sl_pscch_pdu.pscch_numsym;
|
||||
// This provides the offset of the candidate of PSCCH in RBs instead of CCEs
|
||||
rel15->CCE[0] = 0;
|
||||
phy_data->phy_pdcch_config.nb_search_space = 1;
|
||||
pdcch_processing(ue, proc, phy_data,1);
|
||||
|
||||
LOG_D(NR_PHY,"returned from pscch processing\n");
|
||||
}
|
||||
else if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SCI) {
|
||||
sl_nr_rx_config_pssch_sci_pdu_t *pssch_pdu = &phy_data->nr_sl_pssch_sci_pdu;
|
||||
LOG_D(NR_PHY,"sci2_len = %d\n",pssch_pdu->sci2_len);
|
||||
LOG_D(NR_PHY,"sci2_beta_offset = %d\n",pssch_pdu->sci2_beta_offset);
|
||||
LOG_D(NR_PHY,"sci2_alpha_times_100= %d\n",pssch_pdu->sci2_alpha_times_100);
|
||||
LOG_D(NR_PHY,"pssch_targetCodeRate = %d\n",pssch_pdu->targetCodeRate);
|
||||
LOG_D(NR_PHY,"pssch_num_layers = %d\n",pssch_pdu->num_layers);
|
||||
LOG_D(NR_PHY,"dmrs_symbol_position = %d\n",pssch_pdu->dmrs_symbol_position);
|
||||
int num_dmrs = 0;
|
||||
for (int s = 0; s < pssch_pdu->pssch_numsym; s++)
|
||||
num_dmrs += (pssch_pdu->dmrs_symbol_position >> s) & 1;
|
||||
LOG_D(NR_PHY,"num_dmrs = %d\n",num_dmrs);
|
||||
LOG_D(NR_PHY,"Nid = %x\n",pssch_pdu->Nid);
|
||||
|
||||
LOG_D(NR_PHY,"startrb = %d\n",pssch_pdu->startrb);
|
||||
LOG_D(NR_PHY,"pscch_numsym = %d\n",pssch_pdu->pscch_numsym);
|
||||
LOG_D(NR_PHY,"pscch_numrbs = %d\n",pssch_pdu->pscch_numrbs);
|
||||
LOG_D(NR_PHY,"num_subch= %d\n",pssch_pdu->num_subch);
|
||||
LOG_D(NR_PHY,"subchannel_size = %d\n",pssch_pdu->subchannel_size);
|
||||
LOG_D(NR_PHY,"l_subch = %d\n",pssch_pdu->l_subch);
|
||||
LOG_D(NR_PHY,"pssch_numsym = %d\n",pssch_pdu->pssch_numsym);
|
||||
LOG_D(NR_PHY,"sense_pssch = %d\n",pssch_pdu->sense_pssch);
|
||||
ue->slsch->harq_process->pssch_pdu = &phy_data->nr_sl_pssch_sci_pdu;
|
||||
uint8_t freq_density = 0;
|
||||
uint8_t nr_of_rbs = 0;
|
||||
if (is_csi_rs_slot) {
|
||||
AssertFatal(1==0,"Don't do SL CSIRS for now\n");
|
||||
/*
|
||||
freq_density = ue->csirs_vars[0]->csirs_config_pdu.freq_density;
|
||||
nr_of_rbs = ue->csirs_vars[0]->csirs_config_pdu.nr_of_rbs;
|
||||
AssertFatal((freq_density == 1) || (nr_of_rbs > 0), "CSI-RS parameters are not properly configured\n");
|
||||
*/
|
||||
}
|
||||
int sci2_re = get_NREsci2(pssch_pdu->sci2_alpha_times_100,
|
||||
pssch_pdu->sci2_len,
|
||||
pssch_pdu->sci2_beta_offset,
|
||||
pssch_pdu->pssch_numsym,
|
||||
pssch_pdu->pscch_numsym,
|
||||
pssch_pdu->pscch_numrbs,
|
||||
pssch_pdu->l_subch,
|
||||
pssch_pdu->subchannel_size,
|
||||
pssch_pdu->targetCodeRate);
|
||||
|
||||
uint32_t rb_size = pssch_pdu->num_subch*pssch_pdu->subchannel_size;
|
||||
int sci1_dmrs_overlap = pssch_pdu->dmrs_symbol_position & dmrs_pscch_mask[pssch_pdu->pscch_numsym-2];
|
||||
|
||||
uint8_t nr_rbs_w_csi_rs = nr_of_rbs / freq_density;
|
||||
uint8_t subcarriers_used = get_nrUE_params()->nb_antennas_tx > 2 ? 2 : get_nrUE_params()->nb_antennas_tx;
|
||||
int num_CSI_REs = is_csi_rs_slot ? nr_rbs_w_csi_rs * subcarriers_used : 0;
|
||||
uint16_t sci1_re = pssch_pdu->pscch_numsym * pssch_pdu->pscch_numrbs * NR_NB_SC_PER_RB;
|
||||
uint16_t start_symbol = 1;
|
||||
uint16_t number_symbols = pssch_pdu->pssch_numsym;
|
||||
uint8_t number_dmrs_symbols = 0;
|
||||
for (int l = start_symbol; l < start_symbol + number_symbols; l++)
|
||||
number_dmrs_symbols += ((pssch_pdu->dmrs_symbol_position)>>l)&0x01;
|
||||
uint32_t G = nr_get_G_SL(rb_size,
|
||||
pssch_pdu->pssch_numsym,
|
||||
num_dmrs,
|
||||
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
|
||||
sci1_dmrs_overlap,
|
||||
sci1_re,
|
||||
pssch_pdu->pscch_numrbs,
|
||||
sci2_re,
|
||||
num_CSI_REs,
|
||||
pssch_pdu->mod_order,
|
||||
pssch_pdu->num_layers);
|
||||
LOG_D(NR_PHY,"Starting slot FEP for SLSCH (symbol %d to %d) pscch_numsym %d pssch_numsym %d REs with SCI2 %d G %d\n",
|
||||
1 + pssch_pdu->pscch_numsym, pssch_pdu->pssch_numsym,
|
||||
pssch_pdu->pscch_numsym, pssch_pdu->pssch_numsym, sci2_re, G);
|
||||
for (int sym=1+pssch_pdu->pscch_numsym; sym<=pssch_pdu->pssch_numsym;sym++) {
|
||||
nr_slot_fep(ue, fp, proc->nr_slot_rx, sym, rxdataF, link_type_sl, 0, ue->common_vars.rxdata);
|
||||
}
|
||||
|
||||
int16_t *llrs = (int16_t*)__builtin_alloca_with_align(G*sizeof(int16_t),64);
|
||||
nr_rx_pssch(ue,
|
||||
proc,
|
||||
phy_data,
|
||||
rxdataF_sz,
|
||||
rxdataF,
|
||||
llrs,
|
||||
0,
|
||||
frame_rx,
|
||||
nr_slot_rx,
|
||||
0,
|
||||
&is_csi_rs_slot);
|
||||
if (phy_data->sl_rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_PSFCH) {
|
||||
ack_nack_rcvd = calloc(phy_data->num_psfch_pdus, sizeof(ack_nack_rcvd));
|
||||
LOG_D(NR_PHY, "num_psfch_pdus: %d\n", phy_data->num_psfch_pdus);
|
||||
for (int k = 0; k < phy_data->num_psfch_pdus; k++) {
|
||||
sl_nr_tx_rx_config_psfch_pdu_t *psfch_pdu = &phy_data->psfch_pdu_list[k];
|
||||
LOG_D(NR_PHY, "%s start_symbol_index %d, sl_bwp_start %d, sequence_hop_flag %d, \
|
||||
second_hop_prb %d, prb %d, nr_of_symbols %d, initial_cyclic_shift %d, hopping_id %d, \
|
||||
group_hop_flag %d, freq_hop_flag %d, bit_len_harq %d\n",
|
||||
__FUNCTION__,
|
||||
psfch_pdu->start_symbol_index, psfch_pdu->sl_bwp_start,
|
||||
psfch_pdu->sequence_hop_flag, psfch_pdu->second_hop_prb, psfch_pdu->prb,
|
||||
psfch_pdu->nr_of_symbols, psfch_pdu->initial_cyclic_shift, psfch_pdu->hopping_id,
|
||||
psfch_pdu->group_hop_flag, psfch_pdu->freq_hop_flag, psfch_pdu->bit_len_harq);
|
||||
nr_slot_fep(ue, fp, proc->nr_slot_rx, psfch_pdu->start_symbol_index, rxdataF, link_type_sl, 0, ue->common_vars.rxdata);
|
||||
ack_nack_rcvd[k] = 0; // TODO missing: nr_ue_decode_psfch0(ue, frame_rx, nr_slot_rx, rxdataF, psfch_pdu);
|
||||
}
|
||||
free(phy_data->psfch_pdu_list);
|
||||
phy_data->psfch_pdu_list = NULL;
|
||||
}
|
||||
NR_gNB_PUSCH *pssch_vars = &ue->pssch_vars[0];
|
||||
pssch_vars->ulsch_power_tot = 0;
|
||||
pssch_vars->ulsch_noise_power_tot = 0;
|
||||
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||
pssch_vars->ulsch_power[aarx] /= num_dmrs;
|
||||
pssch_vars->ulsch_power_tot += pssch_vars->ulsch_power[aarx];
|
||||
pssch_vars->ulsch_noise_power[aarx] /= num_dmrs;
|
||||
pssch_vars->ulsch_noise_power_tot += pssch_vars->ulsch_noise_power[aarx];
|
||||
}
|
||||
if (dB_fixed_x10(pssch_vars->ulsch_power_tot) < dB_fixed_x10(pssch_vars->ulsch_noise_power_tot) + ue->pssch_thres) {
|
||||
|
||||
LOG_D(NR_PHY,
|
||||
"PSSCH not detected in %d.%d (%d,%d,%d)\n",
|
||||
frame_rx,
|
||||
nr_slot_rx,
|
||||
dB_fixed_x10(pssch_vars->ulsch_power_tot),
|
||||
dB_fixed_x10(pssch_vars->ulsch_noise_power_tot),
|
||||
ue->pssch_thres);
|
||||
pssch_vars->ulsch_power_tot = pssch_vars->ulsch_noise_power_tot;
|
||||
pssch_vars->DTX = 1;
|
||||
//if (stats)
|
||||
// stats->ulsch_stats.DTX++;
|
||||
// nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid, 1, 1);
|
||||
//pssch_DTX++;
|
||||
// continue;
|
||||
} else {
|
||||
pssch_vars->DTX = 0;
|
||||
int totalDecode = nr_slsch_procedures(ue, frame_rx, nr_slot_rx, 0, proc, phy_data, is_csi_rs_slot, ack_nack_rcvd, phy_data->num_psfch_pdus);
|
||||
LOG_D(NR_PHY,
|
||||
"Total %d decoded PSSCH detected in %d.%d (%d,%d,%d)\n",
|
||||
totalDecode,
|
||||
frame_rx,
|
||||
nr_slot_rx,
|
||||
dB_fixed_x10(pssch_vars->ulsch_power_tot),
|
||||
dB_fixed_x10(pssch_vars->ulsch_noise_power_tot),
|
||||
ue->pssch_thres);
|
||||
}
|
||||
}
|
||||
UEscopeCopy(ue, commonRxdataF, rxdataF, sizeof(int32_t), fp->nb_antennas_rx, rxdataF_sz, 0);
|
||||
|
||||
return sampleShift;
|
||||
@@ -246,6 +611,10 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
int slot_tx = proc->nr_slot_tx;
|
||||
int frame_tx = proc->frame_tx;
|
||||
int tx_action = 0;
|
||||
const char *sl_tx_actions[] = {"PSBCH", "PSCCH_PSSCH", "PSCCH_PSSCH_PSFCH", "PSCCH_PSSCH_CSI_RS"};
|
||||
if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS) {
|
||||
LOG_D(NR_PHY, "Generating %s (%d.%d)\n", sl_tx_actions[phy_data->sl_tx_action - SL_NR_CONFIG_TYPE_TX_PSBCH], frame_tx, slot_tx);
|
||||
}
|
||||
|
||||
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
|
||||
NR_DL_FRAME_PARMS *fp = &sl_phy_params->sl_frame_params;
|
||||
@@ -282,7 +651,54 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
}
|
||||
tx_action = 1;
|
||||
}
|
||||
else if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH ||
|
||||
phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS ||
|
||||
phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_PSFCH) {
|
||||
if (phy_data->sl_tx_action >= SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH && phy_data->sl_tx_action <= SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS)
|
||||
LOG_D(NR_PHY, "(%d.%d) Sending %s\n", frame_tx, slot_tx, sl_tx_actions[phy_data->sl_tx_action - SL_NR_CONFIG_TYPE_TX_PSBCH]);
|
||||
phy_data->pscch_Nid = nr_generate_sci1(ue, txdataF[0], fp, AMP, slot_tx, &phy_data->nr_sl_pssch_pscch_pdu) &0xFFFF;
|
||||
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)&phy_data->nr_sl_pssch_pscch_pdu.nr_sl_csi_rs_pdu;
|
||||
csi_params->scramb_id = phy_data->pscch_Nid % (1 << 10);
|
||||
nr_ue_slsch_procedures(ue, phy_data->nr_sl_pssch_pscch_pdu.harq_pid, frame_tx, slot_tx, phy_data, txdataF);
|
||||
|
||||
sl_phy_params->pscch.num_pscch_tx ++;
|
||||
sl_phy_params->pssch.num_pssch_sci2_tx ++;
|
||||
sl_phy_params->pssch.num_pssch_tx ++;
|
||||
if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_CSI_RS) {
|
||||
uint16_t beta_csirs = get_softmodem_params()->sl_mode ? (uint16_t)(AMP * (ceil(sqrt(phy_data->nr_sl_pssch_pscch_pdu.num_layers / fp->nb_antennas_tx)))) & 0xFFFF : AMP;
|
||||
LOG_D(NR_PHY, "Tx beta_csirs: %d, scramb_id %i (%d.%d)\n", beta_csirs, csi_params->scramb_id, frame_tx, slot_tx);
|
||||
AssertFatal(false, "CSI_RS not supported\n");
|
||||
//nr_generate_csi_rs(fp,
|
||||
// (int32_t **)txdataF,
|
||||
// beta_csirs,
|
||||
// ue->nr_csi_info,
|
||||
// csi_params,
|
||||
// slot_tx,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL,
|
||||
// NULL);
|
||||
}
|
||||
if (phy_data->sl_tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_PSFCH) {
|
||||
for (int k = 0; k < phy_data->nr_sl_pssch_pscch_pdu.num_psfch_pdus; k++) {
|
||||
nr_generate_psfch0(ue,
|
||||
txdataF,
|
||||
fp,
|
||||
AMP,
|
||||
slot_tx,
|
||||
&phy_data->nr_sl_pssch_pscch_pdu.psfch_pdu_list[k]);
|
||||
}
|
||||
sl_phy_params->psfch.num_psfch_tx ++;
|
||||
free(phy_data->nr_sl_pssch_pscch_pdu.psfch_pdu_list);
|
||||
phy_data->nr_sl_pssch_pscch_pdu.psfch_pdu_list = NULL;
|
||||
}
|
||||
tx_action = 1;
|
||||
}
|
||||
|
||||
bool was_symbol_used[NR_SYMBOLS_PER_SLOT];
|
||||
for (int i = 0; i < 14; i++)
|
||||
was_symbol_used[i] = true;
|
||||
@@ -301,3 +717,4 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
stop_meas(&sl_phy_params->phy_proc_sl_tx);
|
||||
}
|
||||
|
||||
|
||||
@@ -1294,7 +1294,7 @@ int main(int argc, char **argv)
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
|
||||
pbch_processing(UE, &UE_proc, &phy_data);
|
||||
pdcch_processing(UE, &UE_proc, &phy_data);
|
||||
pdcch_processing(UE, &UE_proc, &phy_data,0);
|
||||
pdsch_processing(UE,
|
||||
&UE_proc,
|
||||
&phy_data);
|
||||
|
||||
@@ -46,6 +46,7 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) { return (NULL); }
|
||||
// to solve link errors
|
||||
double cpuf;
|
||||
// void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
|
||||
@@ -624,7 +625,7 @@ int main(int argc, char **argv)
|
||||
sl_uerx->psbch.rx_ok = 1;
|
||||
}
|
||||
} else
|
||||
psbch_pscch_processing(UE_RX, &proc, &phy_data_rx);
|
||||
psbch_pscch_pssch_processing(UE_RX, &proc, &phy_data_rx);
|
||||
|
||||
} // noise trials
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ int main(int argc, char **argv)
|
||||
if (input_fd == NULL) {
|
||||
uint8_t ULSCH_ids[] = {0};
|
||||
nr_ulsch_pre_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids);
|
||||
nr_ulsch_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids);
|
||||
nr_ulsch_encoding(UE, ulsch_ue, NULL, 0, 0, 0, &G, 1, ULSCH_ids);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
@@ -1943,198 +1943,6 @@ static const int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l[12][8] = {
|
||||
{0, 3072, -1, -1, 3, 1539, -1, -1}, // 14 // (DMRS l' position)
|
||||
};
|
||||
|
||||
// the following tables contain 10 times the value reported in 214 (in line with SCF specification and to avoid fractional values)
|
||||
//Table 5.1.3.1-1 of 38.214
|
||||
static const uint16_t Table_51311[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
|
||||
{2, 6020}, {2, 6790}, {4, 3400}, {4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160},
|
||||
{4, 6580}, {6, 4380}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7190},
|
||||
{6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
// Table 5.1.3.1-2 of 38.214
|
||||
static const uint16_t Table_51312[32][2] = {{2, 1200}, {2, 1930}, {2, 3080}, {2, 4490}, {2, 6020}, {4, 3780}, {4, 4340},
|
||||
{4, 4900}, {4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670},
|
||||
{6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {8, 6825},
|
||||
{8, 7110}, {8, 7540}, {8, 7970}, {8, 8410}, {8, 8850}, {8, 9165}, {8, 9480},
|
||||
{2, 0}, {4, 0}, {6, 0}, {8, 0}};
|
||||
|
||||
//Table 5.1.3.1-3 of 38.214
|
||||
static const uint16_t Table_51313[32][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200}, {2, 1570},
|
||||
{2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260}, {2, 6020}, {4, 3400},
|
||||
{4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160}, {6, 4380}, {6, 4660}, {6, 5170},
|
||||
{6, 5670}, {6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
static const uint16_t Table_61411[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490},
|
||||
{2, 5260}, {2, 6020}, {2, 6790}, {4, 3400}, {4, 3780}, {4, 4340}, {4, 4900},
|
||||
{4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160},
|
||||
{6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480},
|
||||
{2, 0}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
static const uint16_t Table_61412[32][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200},
|
||||
{2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
|
||||
{2, 6020}, {2, 6790}, {4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160},
|
||||
{4, 6580}, {4, 6990}, {4, 7720}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7720},
|
||||
{2, 0}, {2, 0}, {4, 0}, {6, 0}};
|
||||
|
||||
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61411[Imcs][0]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61412[Imcs][0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
|
||||
switch(table_idx) {
|
||||
case 0:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51311[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51312[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_51313[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61411[Imcs][1]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (Imcs > 31) {
|
||||
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,31])\n", Imcs);
|
||||
return 0;
|
||||
}
|
||||
return (Table_61412[Imcs][1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Table 5.1.2.2.1-1 38.214
|
||||
uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config)
|
||||
{
|
||||
|
||||
@@ -190,13 +190,6 @@ uint32_t nr_compute_tbs(uint16_t Qm,
|
||||
uint8_t tb_scaling,
|
||||
uint8_t Nl);
|
||||
|
||||
/** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */
|
||||
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx);
|
||||
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx);
|
||||
|
||||
/** \brief Computes Q based on I_MCS PDSCH and table_idx for uplink. Implements MCS Tables from 38.214. */
|
||||
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx);
|
||||
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx);
|
||||
int srs_binomial_sum(int count, int Lmax);
|
||||
int srs_codebook_nb_res(NR_SRS_Config_t *srs_config);
|
||||
int srs_non_codebook_nb_res(NR_SRS_Config_t *srs_config);
|
||||
|
||||
@@ -334,7 +334,7 @@ static void sl_schedule_rx_actions(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_I
|
||||
} else if (rx_action >= SL_NR_CONFIG_TYPE_RX_PSCCH && rx_action <= SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH) {
|
||||
// TBD..
|
||||
|
||||
} else if (rx_action == SL_NR_CONFIG_TYPE_RX_PSFCH) {
|
||||
} else if (rx_action == SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH_PSFCH) {
|
||||
// TBD..
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ static void sl_schedule_tx_actions(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_I
|
||||
} else if (tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH) {
|
||||
// TBD....
|
||||
|
||||
} else if (tx_action == SL_NR_CONFIG_TYPE_TX_PSFCH) {
|
||||
} else if (tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH_PSFCH) {
|
||||
// TBD....
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user