diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 6e588acd1d..856d53ff99 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1056,11 +1056,11 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, uint8_t harq_pid); /*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1 - @param[in] in Pointer to input bits - @param[in] size of input bits - @param[in] Nid cell id - @param[in] n_RNTI CRNTI - @param[out] out the scrambled bits + @param[in] in, Pointer to input bits + @param[in] size, of input bits + @param[in] Nid, cell id + @param[in] n_RNTI, CRNTI + @param[out] out, the scrambled bits */ void nr_pusch_codeword_scrambling(uint8_t *in, @@ -1070,6 +1070,19 @@ void nr_pusch_codeword_scrambling(uint8_t *in, uint32_t* out); +/*! \brief Perform PUSCH modulation. TS 38.211 V15.4.0 subclause 6.3.1.2 + @param[in] in, Pointer to input bits + @param[in] Qm, modulation order + @param[in] length, size of input bits + @param[out] out, complex valued modulated symbols +*/ + +void nr_pusch_codeword_modulation(uint32_t *in, + uint8_t Qm, + uint32_t length, + int16_t *out); + + uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, int eNB_id, @@ -1115,7 +1128,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue, @param first_symbol_flag set to 1 on first DLSCH symbol @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice. @param i_mod Modulation order of the interfering stream -*/ + int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue, PDSCH_t type, uint8_t eNB_id, @@ -1127,7 +1140,7 @@ int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue, RX_type_t rx_type, uint8_t i_mod, uint8_t harq_pid); - +*/ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, uint32_t frame, uint8_t nr_tti_rx, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c index 574e19eb5f..286ee6c48f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch.c @@ -30,7 +30,11 @@ * \warning */ #include +#include "common/utils/assertions.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" +#include "PHY/defs_nr_common.h" + +extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; @@ -63,4 +67,29 @@ void nr_pusch_codeword_scrambling(uint8_t *in, //printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out); } -} \ No newline at end of file +} + +// This function is copied from PHY/NR_TRANSPORT/nr_dlsch.c +void nr_pusch_codeword_modulation(uint32_t *in, + uint8_t Qm, + uint32_t length, + int16_t *out) { + + uint16_t offset = (Qm==2)? NR_MOD_TABLE_QPSK_OFFSET : (Qm==4)? NR_MOD_TABLE_QAM16_OFFSET : \ + (Qm==6)? NR_MOD_TABLE_QAM64_OFFSET: (Qm==8)? NR_MOD_TABLE_QAM256_OFFSET : 0; + AssertFatal(offset, "Invalid modulation order %d\n", Qm); + + for (int i=0; i>b_idx)&1)<<(Qm-j-1); + } + + out[i<<1] = nr_mod_table[(offset+idx)<<1]; + out[(i<<1)+1] = nr_mod_table[((offset+idx)<<1)+1]; + } +} diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 7c557e6134..328bbf8c43 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -562,7 +562,7 @@ int main(int argc, char **argv) { //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); // generate signal - /////////////////////////[adk] ULSCH coding///////////////////////// + /////////////////////////ULSCH coding///////////////////////// /////////// if (input_fd == NULL) { @@ -572,7 +572,7 @@ int main(int argc, char **argv) { /////////// //////////////////////////////////////////////////////////////////// - /////////////////////////[adk] ULSCH scrambling///////////////////////// + /////////////////////////ULSCH scrambling///////////////////////// /////////// uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; @@ -594,6 +594,18 @@ int main(int argc, char **argv) { ///////////// ////////////////////////////////////////////////////////////////////////// + /////////////////////////ULSCH modulation///////////////////////// + /////////// + + nr_pusch_codeword_modulation(scrambled_output[0], // assume one codeword for the moment + mod_order, + encoded_length, + ulsch_ue->d); + + + /////////// + //////////////////////////////////////////////////////////////////////// + for (SNR = snr0; SNR < snr1; SNR += snr_step) { n_errors = 0; n_false_positive = 0;