From aed0cfe2af9d7926d4dad08693ff20164439a12b Mon Sep 17 00:00:00 2001 From: Daniel Andrade Date: Fri, 23 Jun 2023 14:31:43 +0100 Subject: [PATCH 01/19] Bugfix for getting band and numerology from command line for OAI UE --- executables/nr-uesoftmodem.c | 2 +- executables/softmodem-common.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 7896e57145..f2420641fd 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -513,7 +513,7 @@ int main( int argc, char **argv ) { NR_UE_MAC_INST_t *mac = get_mac_inst(0); if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid - uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); + uint16_t nr_band = get_softmodem_params()->band; mac->nr_band = nr_band; nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms, downlink_frequency[CC_id][0], diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 1f37c9bdea..9f792b158c 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -162,8 +162,8 @@ extern int usrp_tx_thread; {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \ {"dqt" , CONFIG_HLP_SOFTS_QT, PARAMFLAG_BOOL, .uptr=&do_forms_qt, .defintval=0, TYPE_UINT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&opp_enabled, .defintval=0, TYPE_INT, 0}, \ - {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \ - {"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \ + {"numerology" , CONFIG_HLP_NUMEROLOGY, 0, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \ + {"band" , CONFIG_HLP_BAND, 0, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \ {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, .iptr=&EMULATE_RF, .defintval=0, TYPE_INT, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, .strptr=¶llel_config, .defstrval=NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, .strptr=&worker_config, .defstrval=NULL, TYPE_STRING, 0}, \ From 26a69234b2d3efc443c5c74853a6327e61574791 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 13 Jun 2023 11:04:38 +0200 Subject: [PATCH 02/19] Fix UB problems in F1: right TEID conversion, which is unsigned --- openair2/F1AP/f1ap_common.c | 2 +- openair2/F1AP/f1ap_cu_ue_context_management.c | 4 ++-- openair2/F1AP/f1ap_du_rrc_message_transfer.c | 2 +- openair2/F1AP/f1ap_du_ue_context_management.c | 4 ++-- openair3/UTILS/conversions.h | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index 862e701b6d..f417a1c337 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -36,7 +36,7 @@ static f1ap_cudu_inst_t *f1_du_inst[NUMBER_OF_gNB_MAX]= {0}; static f1ap_cudu_inst_t *f1_cu_inst[NUMBER_OF_gNB_MAX]= {0}; uint8_t F1AP_get_next_transaction_identifier(instance_t mod_idP, instance_t cu_mod_idP) { - static uint8_t transaction_identifier[NUMBER_OF_gNB_MAX]; + static uint8_t transaction_identifier[NUMBER_OF_gNB_MAX] = {0}; transaction_identifier[mod_idP+cu_mod_idP] = (transaction_identifier[mod_idP+cu_mod_idP] + 1) % F1AP_TRANSACTION_IDENTIFIER_NUMBER; return transaction_identifier[mod_idP+cu_mod_idP]; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index a38dd7c68f..8fdee52abb 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -693,7 +693,7 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setup_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0]; F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); - OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); + OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst, f1ap_ue_context_setup_resp->rnti, (ebi_t)drbs_setup_item_p->dRBID, @@ -1654,7 +1654,7 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0]; F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); - OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); + OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst, f1ap_ue_context_modification_resp->rnti, (ebi_t)drbs_setupmod_item_p->dRBID, diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 997105d92a..5fc8daef3f 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -219,7 +219,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie6->id = F1AP_ProtocolIE_ID_id_TransactionID; ie6->criticality = F1AP_Criticality_ignore; ie6->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_TransactionID; - ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(f1ap_req(false, instanceP)->gNB_DU_id, f1ap_req(false, instanceP)->gNB_DU_id); + ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(0, 0); /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index ccd3381e95..05833e3fad 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -161,7 +161,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0]; F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address); - OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid); + OCTET_STRING_TO_UINT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid); // 3GPP assumes GTP-U is on port 2152, but OAI is configurable drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport; @@ -877,7 +877,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t asso F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0]; F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address); - OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid); + OCTET_STRING_TO_UINT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid); // 3GPP assumes GTP-U is on port 2152, but OAI is configurable drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport; diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index 2c544c94e0..bf24c9f4ee 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -119,10 +119,10 @@ do { \ /* Convert an array of char containing vALUE to x */ #define BUFFER_TO_UINT32(buf, x) \ do { \ - x = (((uint32_t)(buf)[0] << 24) | \ - (uint32_t)((buf)[1] << 16) | \ - (uint32_t)((buf)[2] << 8) | \ - (uint32_t)((buf)[3]); \ + x = (((uint32_t)((buf)[0])) << 24) | \ + (((uint32_t)((buf)[1])) << 16) | \ + (((uint32_t)((buf)[2])) << 8) | \ + (((uint32_t)((buf)[3]))); \ } while (0) /* Convert an integer on 32 bits to an octet string from aSN1c tool */ From 7d9b4db58036c25470601657863a44e62d3a22bd Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 26 Jun 2023 11:23:52 +0200 Subject: [PATCH 03/19] Correctly copy in_addr for GTP F1 tunnel update --- openair2/RRC/NR/cucp_cuup_direct.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index 4591537304..347e9fbff5 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -85,16 +85,13 @@ void CU_update_UP_DL_tunnel(e1ap_bearer_setup_req_t *const req, instance_t insta for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) { DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j; - transport_layer_addr_t newRemoteAddr; - newRemoteAddr.length = 32; // IPv4 - memcpy(newRemoteAddr.buffer, - &drb_p->DlUpParamList[0].tlAddress, - sizeof(in_addr_t)); + in_addr_t addr = {0}; + memcpy(&addr, &drb_p->DlUpParamList[0].tlAddress, sizeof(in_addr_t)); GtpuUpdateTunnelOutgoingAddressAndTeid(instance, (ue_id & 0xFFFF), (ebi_t)drb_p->id, - *(in_addr_t*)&newRemoteAddr.buffer, + addr, drb_p->DlUpParamList[0].teId); } } From dcae67c375fac792d68135180b27a7cdb7b30cff Mon Sep 17 00:00:00 2001 From: rmagueta Date: Fri, 23 Jun 2023 14:22:53 +0100 Subject: [PATCH 04/19] Bugfix for PDCCH monitoring occasions tables and SFN computation for FR2 --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 8 +------ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 22 +++++++++---------- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 +- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 9465d69e8b..c15a5cd194 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -483,19 +483,13 @@ typedef enum nr_ssb_and_cset_mux_pattern_type_e { NR_SSB_AND_CSET_MUX_PATTERN_TYPE3 } nr_ssb_and_cset_mux_pattern_type_t; -typedef enum { - SFN_C_MOD_2_EQ_0, - SFN_C_MOD_2_EQ_1, - SFN_C_IMPOSSIBLE -} SFN_C_TYPE; - typedef struct Type0_PDCCH_CSS_config_s { int32_t num_rbs; int32_t num_symbols; int32_t rb_offset; // Offset from SSB RB0 uint32_t type0_pdcch_ss_mux_pattern; uint16_t frame; - SFN_C_TYPE sfn_c; + int sfn_c; uint32_t n_c; uint32_t n_0; uint32_t number_of_search_space_per_slot; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 67d1e4fc5f..e9fa641a07 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -164,12 +164,12 @@ const int32_t table_38213_13_10_c4[16] = { 0, 8, 0, 8,-41, 25,-41, 49, reserv const float table_38213_13_11_c1[16] = { 0, 0, 2, 2, 5, 5, 7, 7, 0, 5, 0, 0, 2, 2, 5, 5}; // O const int32_t table_38213_13_11_c2[16] = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1}; -const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 1, 1, 1, 1, 1, 1, 1}; // M +const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 2, 2, 1, 1, 1, 1, 1, 1}; // M const int32_t table_38213_13_11_c4[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2}; // i is even as default const float table_38213_13_12_c1[16] = { 0, 0, 2.5f, 2.5f, 5, 5, 0, 2.5f, 5, 7.5f, 7.5f, 7.5f, 0, 5, reserved, reserved}; // O, index 14-15 reserved const int32_t table_38213_13_12_c2[16] = { 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, reserved, reserved}; // index 14-15 reserved -const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 1, reserved, reserved}; // M, index 14-15 reserved +const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 2, 2, reserved, reserved}; // M, index 14-15 reserved const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 }; @@ -4301,7 +4301,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD // type0-pdcch search space float big_o = 0.0f; float big_m = 0.0f; - type0_PDCCH_CSS_config->sfn_c = SFN_C_IMPOSSIBLE; // only valid for mux=1 + type0_PDCCH_CSS_config->sfn_c = -1; // only valid for mux=1 type0_PDCCH_CSS_config->n_c = UINT_MAX; type0_PDCCH_CSS_config->number_of_search_space_per_slot = UINT_MAX; type0_PDCCH_CSS_config->first_symbol_index = UINT_MAX; @@ -4316,11 +4316,7 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD uint32_t temp = (uint32_t)(big_o*(1<ssb_index*big_m); type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame; - if((temp/num_slot_per_frame) & 0x1){ - type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1; - }else{ - type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_0; - } + type0_PDCCH_CSS_config->sfn_c = type0_PDCCH_CSS_config->n_c % 2; if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (type0_PDCCH_CSS_config->ssb_index&1)){ type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols; @@ -4335,9 +4331,13 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){ big_o = table_38213_13_12_c1[index_4lsb]; - type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; + type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_12_c2[index_4lsb]; big_m = table_38213_13_12_c3[index_4lsb]; + uint32_t temp = (uint32_t)(big_o*(1<ssb_index*big_m); + type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame; + type0_PDCCH_CSS_config->sfn_c = type0_PDCCH_CSS_config->n_c % 2; + if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (type0_PDCCH_CSS_config->ssb_index&1)){ type0_PDCCH_CSS_config->first_symbol_index = 7; }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (type0_PDCCH_CSS_config->ssb_index&1)){ @@ -4461,8 +4461,8 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD // AssertFatal(first_symbol_index!=UINT_MAX,""); // mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; - AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,""); - AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,""); + AssertFatal(type0_PDCCH_CSS_config->sfn_c >= 0, ""); + AssertFatal(type0_PDCCH_CSS_config->n_c != UINT_MAX, ""); type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<ssb_index*big_m))%num_slot_per_frame; type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 99c7ba6dcd..4eee1bb3fe 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -420,7 +420,7 @@ typedef struct { /// Type0-PDCCH seach space fapi_nr_dl_config_dci_dl_pdu_rel15_t type0_pdcch_dci_config; uint32_t type0_pdcch_ss_mux_pattern; - SFN_C_TYPE type0_pdcch_ss_sfn_c; + int type0_pdcch_ss_sfn_c; uint32_t type0_pdcch_ss_n_c; uint32_t type0_pdcch_consecutive_slots; From 659d52931514f63fc691c2c653e16d9c69e20575 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 13 Jun 2023 14:25:26 +0100 Subject: [PATCH 05/19] Enable T304 --- openair2/RRC/NR_UE/rrc_UE.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 69efec94ce..27f53b673c 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1208,7 +1208,9 @@ void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP, set_default_timers_and_constants(&rrc->timers_and_constants); LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__); NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync; + rrc->timers_and_constants.T304_active = true; nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync); + // TODO: Implementation of the remaining procedures regarding the reception of the reconfigurationWithSync, TS 38.331 - Section 5.3.5.5.2 } if (rrc->cell_group_config && @@ -2287,7 +2289,7 @@ void *rrc_nrue_task(void *args_p) break; case NRRRC_SLOT_PROCESS: - LOG_D(NR_RRC, "[UE %d] Receided %s: frame %d slot %d\n", + LOG_D(NR_RRC, "[UE %d] Received %s: frame %d slot %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NRRRC_SLOT_PROCESS (msg_p).frame, NRRRC_SLOT_PROCESS (msg_p).slot); NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants; nr_rrc_handle_timers(timers); From 8fffe50a115b7ebc131de1aed3bfb8b047c30005 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Fri, 17 Mar 2023 14:18:39 +0000 Subject: [PATCH 06/19] Fix rho computation --- .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 84baea9844..070968760b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1100,8 +1100,10 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, if (n_rx > 1) { #if defined(__x86_64__) || defined(__i386__) - for (int aatx=0; aatxnb_antennas_rx][(symbol*(nb_re + off))]; ul_ch_mag128[0] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx][(symbol*(nb_re + off))]; @@ -1123,6 +1125,20 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, //rxdataF_comp128[0][i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i *)&jitterc[0])); } } + + if (rho) { + __m128i *rho128[2]; + for (int aatx2 = 0; aatx2 < nrOfLayers; aatx2++) { + rho128[0] = (__m128i *) &rho[0][aatx * nrOfLayers + aatx2][(symbol * (nb_re + off))]; + for (int aa = 1; aa < n_rx; aa++) { + rho128[1] = (__m128i *) &rho[aa][aatx * nrOfLayers + aatx2][(symbol * (nb_re + off))]; + for (i = 0; i < nb_rb_0 * 3; i++) { + rho128[0][i] = _mm_adds_epi16(rho128[0][i], rho128[1][i]); + } + } + } + } + } #elif defined(__arm__) || defined(__aarch64__) rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12]; From e21a09967dfc32c5fc0f85a3fb0b4f036dc5fe59 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 15 Mar 2023 15:52:06 +0000 Subject: [PATCH 07/19] Compute LLR for QPSK for ML --- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 12 + .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 65 +++-- .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 264 ++++++++++++++++++ 3 files changed, 325 insertions(+), 16 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 0509ce7acf..306d44f8f5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -292,6 +292,18 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, void reset_active_stats(PHY_VARS_gNB *gNB, int frame); void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame); +void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, + int32_t ***rho, + int16_t **llr_layers, + uint8_t nb_antennas_rx, + uint32_t rb_size, + uint32_t nb_re, + uint8_t symbol, + uint32_t rxdataF_ext_offset, + uint8_t mod_order); + +void nr_ulsch_shift_llr(int16_t **llr_layers, uint32_t nb_re, uint32_t rxdataF_ext_offset, uint8_t mod_order, int shift); + void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 070968760b..56e4575f7a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -12,6 +12,7 @@ //#define DEBUG_CH_COMP //#define DEBUG_RB_EXT //#define DEBUG_CH_MAG +//#define ML_DEBUG #define INVALID_VALUE 255 @@ -636,7 +637,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) QAM_amp128b = _mm_setzero_si128(); QAM_amp128c = _mm_setzero_si128(); - } + } else if (mod_order == 6) { QAM_amp128 = _mm_set1_epi16(QAM64_n1); // QAM_amp128b = _mm_set1_epi16(QAM64_n2); @@ -1081,7 +1082,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, int32_t **ul_ch_mag, int32_t **ul_ch_magb, int32_t **ul_ch_magc, - int32_t ***rho, + int32_t ***rho, uint8_t nrOfLayers, uint8_t symbol, uint16_t nb_rb, @@ -1115,7 +1116,7 @@ void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, ul_ch_mag128[1] = (__m128i *)&ul_ch_mag[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ul_ch_mag128b[1] = (__m128i *)&ul_ch_magb[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; ul_ch_mag128c[1] = (__m128i *)&ul_ch_magc[aatx*frame_parms->nb_antennas_rx+aa][(symbol*(nb_re + off))]; - + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) for (i=0; inrOfLayers == 1) { ad_shift = 1 + log2_approx(frame_parms->nb_antennas_rx >> 2); - } else { - ad_shift = -3; // For 2-layers, we are already doing a bit shift in the nr_ulsch_zero_forcing_rx_2layers() function, so we can use more bits + } else if (ml_rx == false) { + ad_shift = -3; // For 2-layers, we are already doing a bit shift in the nr_ulsch_mmse_2layers() function, so we can use more bits } for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { @@ -2108,7 +2112,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, nb_re_pusch); // Apply MMSE for 2 Tx layers - if (rel15_ul->nrOfLayers == 2) { + if (ml_rx == false && rel15_ul->nrOfLayers == 2) { nr_ulsch_mmse_2layers(frame_parms, pusch_vars->rxdataF_comp, pusch_vars->ul_ch_mag0, @@ -2159,16 +2163,45 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, /*-------------------- LLRs computation -------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------*/ start_meas(&gNB->ulsch_llr_stats); - for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) { - nr_ulsch_compute_llr(&pusch_vars->rxdataF_comp[aatx*frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], - pusch_vars->ul_ch_mag0[aatx*frame_parms->nb_antennas_rx], - pusch_vars->ul_ch_magb0[aatx*frame_parms->nb_antennas_rx], - pusch_vars->ul_ch_magc0[aatx*frame_parms->nb_antennas_rx], - &pusch_vars->llr_layers[aatx][rxdataF_ext_offset * rel15_ul->qam_mod_order], - rel15_ul->rb_size, - pusch_vars->ul_valid_re_per_slot[symbol], - symbol, - rel15_ul->qam_mod_order); + if (ml_rx == false || rel15_ul->nrOfLayers == 1) { + for (aatx=0; aatx < rel15_ul->nrOfLayers; aatx++) { + nr_ulsch_compute_llr(&pusch_vars->rxdataF_comp[aatx * frame_parms->nb_antennas_rx][symbol * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], + pusch_vars->ul_ch_mag0[aatx * frame_parms->nb_antennas_rx], + pusch_vars->ul_ch_magb0[aatx * frame_parms->nb_antennas_rx], + pusch_vars->ul_ch_magc0[aatx * frame_parms->nb_antennas_rx], + &pusch_vars->llr_layers[aatx][rxdataF_ext_offset * rel15_ul->qam_mod_order], + rel15_ul->rb_size, + pusch_vars->ul_valid_re_per_slot[symbol], + symbol, + rel15_ul->qam_mod_order); + } + } else { + nr_ulsch_compute_ML_llr(pusch_vars->rxdataF_comp, + pusch_vars->rho, + pusch_vars->llr_layers, + frame_parms->nb_antennas_rx, + rel15_ul->rb_size, + nb_re_pusch, + symbol, + rxdataF_ext_offset, + rel15_ul->qam_mod_order); + + if (rel15_ul->qam_mod_order == 2) { + nr_ulsch_shift_llr(pusch_vars->llr_layers, nb_re_pusch, rxdataF_ext_offset, rel15_ul->qam_mod_order, 4); + } + +#ifdef ML_DEBUG + c16_t *llr_layers0 = (c16_t *)&pusch_vars->llr_layers[0][rxdataF_ext_offset * rel15_ul->qam_mod_order]; + c16_t *llr_layers1 = (c16_t *)&pusch_vars->llr_layers[1][rxdataF_ext_offset * rel15_ul->qam_mod_order]; + printf("===============================\n"); + printf("AFTER nr_ulsch_compute_ML_llr()\n"); + printf("===============================\n"); + for (int k = 0; k < nb_re_pusch; k++) { + printf("[%3i] llr_layers0 = (%6i, %6i), llr_layers1 = (%6i, %6i)\n", + k, llr_layers0[k].r, llr_layers0[k].i, llr_layers1[k].r, llr_layers1[k].i); + } + printf("\n"); +#endif } stop_meas(&gNB->ulsch_llr_stats); rxdataF_ext_offset += pusch_vars->ul_valid_re_per_slot[symbol]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 4d4c81a986..dc5e117267 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -509,3 +509,267 @@ void nr_ulsch_compute_llr(int32_t *rxdataF_comp, break; } } + +/* + * This function computes the LLRs of stream 0 (s_0) in presence of the interfering stream 1 (s_1) assuming that both symbols are + * QPSK. It can be used for both MU-MIMO interference-aware receiver or for SU-MIMO receivers. + * + * Input: + * stream0_in: MF filter output for 1st stream, i.e., y0' = h0'*y0 + * stream1_in: MF filter output for 2nd stream, i.e., y1' = h1'*y0 + * rho01: Channel cross correlation, i.e., rho01 = h0'*h1 + * length: Number of resource elements + * + * Output: + * stream0_out: Output LLRs for 1st stream + */ +void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, c16_t *stream0_out, c16_t *rho01, uint32_t length) +{ + __m128i *rho01_128i = (__m128i *)rho01; + __m128i *stream0_128i_in = (__m128i *)stream0_in; + __m128i *stream1_128i_in = (__m128i *)stream1_in; + __m128i *stream0_128i_out = (__m128i *)stream0_out; + __m128i ONE_OVER_2_SQRT_2 = _mm_set1_epi16(23170); // round(2 ^ 16 / (2 * sqrt(2))) + + // In each iteration, we take 8 complex symbols + for (int i = 0; i < length >> 2; i += 2) { + + /// Compute real and imaginary parts of MF output for stream 0 (desired stream) + + // Put xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + __m128i xmm0 = stream0_128i_in[i]; // 4 symbols + xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + __m128i xmm1 = stream0_128i_in[i + 1]; // 4 symbols + xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + __m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // y0r = Re(y0) + __m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); // y0i = Im(y0) + + __m128i y0r_over2 = simde_mm_mulhi_epi16(y0r, ONE_OVER_2_SQRT_2); + y0r_over2 = _mm_slli_epi16(y0r_over2, 1); // y0r_over2 = Re(y0) / sqrt(2) + __m128i y0i_over2 = simde_mm_mulhi_epi16(y0i, ONE_OVER_2_SQRT_2); + y0i_over2 = _mm_slli_epi16(y0i_over2, 1); // y0i_over2 = Im(y0) / sqrt(2) + + /// Compute real and imaginary parts of MF output for stream 1 (interference stream) + + // Put xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + xmm0 = stream1_128i_in[i]; // 4 symbols + xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + xmm1 = stream1_128i_in[i + 1]; // 4 symbols + xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + __m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); // y1r = Re(y1) + __m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); // y1i = Im(y1) + __m128i y1r_over2 = simde_mm_srai_epi16(y1r, 1); // y1r_over2 = Re(y1) / 2 + __m128i y1i_over2 = simde_mm_srai_epi16(y1i, 1); // y1i_over2 = Im(y1) / 2 + + /// Get real and imaginary parts of rho + + // Put xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + xmm0 = rho01_128i[i]; // 4 symbols + xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + xmm1 = rho01_128i[i + 1]; // 4 symbols + xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + __m128i rhor = simde_mm_unpacklo_epi64(xmm0, xmm1); // rhor = Re(rho) + __m128i rhoi = simde_mm_unpackhi_epi64(xmm0, xmm1); // rhoi = Im(rho) + + /// Compute |psi_r| and |psi_i| + + // psi_r = rhor * xR + rhoi * xI + // psi_i = rhor * xI - rhoi * xR + + // Put (rho_r + rho_i)/(2*sqrt(2)) in rho_p + // rhor * xR + rhoi * xI --> xR = 1/sqrt(2) and xI = 1/sqrt(2) + // rhor * xI - rhoi * xR --> xR = -1/sqrt(2) and xI = 1/sqrt(2) + __m128i rho_p = simde_mm_adds_epi16(rhor, rhoi); // rho_p = Re(rho) + Im(rho) + rho_p = simde_mm_mulhi_epi16(rho_p, ONE_OVER_2_SQRT_2); // rho_p = rho_p / (2*sqrt(2)) + + // Put (rho_r - rho_i)/(2*sqrt(2)) in rho_m + // rhor * xR + rhoi * xI --> xR = 1/sqrt(2) and xI = -1/sqrt(2) + // rhor * xI - rhoi * xR --> xR = 1/sqrt(2) and xI = 1/sqrt(2) + __m128i rho_m = simde_mm_subs_epi16(rhor, rhoi); // rho_m = Re(rho) - Im(rho) + rho_m = simde_mm_mulhi_epi16(rho_m, ONE_OVER_2_SQRT_2); // rho_m = rho_m / (2*sqrt(2)) + + // xR = 1/sqrt(2) and xI = 1/sqrt(2) + __m128i abs_psi_rpm = simde_mm_subs_epi16(rho_p, y1r_over2); // psi_rpm = rho_p - y1r/2 + abs_psi_rpm = simde_mm_abs_epi16(abs_psi_rpm); // abs_psi_rpm = |psi_rpm| + + // xR = 1/sqrt(2) and xI = 1/sqrt(2) + __m128i abs_psi_imm = simde_mm_subs_epi16(rho_m, y1i_over2); // psi_imm = rho_m - y1i/2 + abs_psi_imm = simde_mm_abs_epi16(abs_psi_imm); // abs_psi_imm = |psi_imm| + + // xR = 1/sqrt(2) and xI = -1/sqrt(2) + __m128i abs_psi_rmm = simde_mm_subs_epi16(rho_m, y1r_over2); // psi_rmm = rho_m - y1r/2 + abs_psi_rmm = simde_mm_abs_epi16(abs_psi_rmm); // abs_psi_rmm = |psi_rmm| + + // xR = -1/sqrt(2) and xI = 1/sqrt(2) + __m128i abs_psi_ipm = simde_mm_subs_epi16(rho_p, y1i_over2); // psi_ipm = rho_p - y1i/2 + abs_psi_ipm = simde_mm_abs_epi16(abs_psi_ipm); // abs_psi_ipm = |psi_ipm| + + // xR = -1/sqrt(2) and xI = -1/sqrt(2) + __m128i abs_psi_rpp = simde_mm_adds_epi16(rho_p, y1r_over2); // psi_rpp = rho_p + y1r/2 + abs_psi_rpp = simde_mm_abs_epi16(abs_psi_rpp); // abs_psi_rpp = |psi_rpp| + + // xR = -1/sqrt(2) and xI = -1/sqrt(2) + __m128i abs_psi_imp = simde_mm_adds_epi16(rho_m, y1i_over2); // psi_imp = rho_m + y1i/2 + abs_psi_imp = simde_mm_abs_epi16(abs_psi_imp); // abs_psi_imp = |psi_imp| + + // xR = -1/sqrt(2) and xI = 1/sqrt(2) + __m128i abs_psi_rmp = simde_mm_adds_epi16(rho_m, y1r_over2); // psi_rmp = rho_m + y1r/2 + abs_psi_rmp = simde_mm_abs_epi16(abs_psi_rmp); // abs_psi_rmp = |psi_rmp| + + // xR = 1/sqrt(2) and xI = -1/sqrt(2) + __m128i abs_psi_ipp = simde_mm_adds_epi16(rho_p, y1i_over2); // psi_ipm = rho_p + y1i/2 + abs_psi_ipp = simde_mm_abs_epi16(abs_psi_ipp); // abs_psi_ipp = |psi_ipm| + + /// Compute bit metrics (lambda) + + // lambda = max { |psi_r - y1r| * |x2R| + |psi_i - y1i| * |x2I| + y0r * xR + y0i * xI} + + // xR = 1/sqrt(2) and xI = 1/sqrt(2) + // For numerator: bit_met_num_re_p = abs_psi_rpm + abs_psi_imm + y0r/sqrt(2) + y0i/sqrt(2) + __m128i bit_met_num_re_p = simde_mm_adds_epi16(abs_psi_rpm, abs_psi_imm); + bit_met_num_re_p = simde_mm_adds_epi16(bit_met_num_re_p, y0r_over2); + bit_met_num_re_p = simde_mm_adds_epi16(bit_met_num_re_p, y0i_over2); + + // xR = 1/sqrt(2) and xI = -1/sqrt(2) + // For numerator: bit_met_num_re_m = abs_psi_rmm + abs_psi_ipp + y0r/sqrt(2) - y0i/sqrt(2) + __m128i bit_met_num_re_m = simde_mm_adds_epi16(abs_psi_rmm, abs_psi_ipp); + bit_met_num_re_m = simde_mm_adds_epi16(bit_met_num_re_m, y0r_over2); + bit_met_num_re_m = simde_mm_subs_epi16(bit_met_num_re_m, y0i_over2); + + // xR = -1/sqrt(2) and xI = 1/sqrt(2) + // For denominator: bit_met_den_re_p = abs_psi_rmp + abs_psi_ipm - y0r/sqrt(2) + y0i/sqrt(2) + __m128i bit_met_den_re_p = simde_mm_adds_epi16(abs_psi_rmp, abs_psi_ipm); + bit_met_den_re_p = simde_mm_subs_epi16(bit_met_den_re_p, y0r_over2); + bit_met_den_re_p = simde_mm_adds_epi16(bit_met_den_re_p, y0i_over2); + + // xR = -1/sqrt(2) and xI = -1/sqrt(2) + // For denominator: bit_met_den_re_m = abs_psi_rpp + abs_psi_imp - y0r/sqrt(2) - y0i/sqrt(2) + __m128i bit_met_den_re_m = simde_mm_adds_epi16(abs_psi_rpp, abs_psi_imp); + bit_met_den_re_m = simde_mm_subs_epi16(bit_met_den_re_m, y0r_over2); + bit_met_den_re_m = simde_mm_subs_epi16(bit_met_den_re_m, y0i_over2); + + // xR = 1/sqrt(2) and xI = 1/sqrt(2) + // For numerator: bit_met_num_im_p = abs_psi_rpm + abs_psi_imm + y0r/sqrt(2) + y0i/sqrt(2) + __m128i bit_met_num_im_p = simde_mm_adds_epi16(abs_psi_rpm, abs_psi_imm); + bit_met_num_im_p = simde_mm_adds_epi16(bit_met_num_im_p, y0r_over2); + bit_met_num_im_p = simde_mm_adds_epi16(bit_met_num_im_p, y0i_over2); + + // xR = -1/sqrt(2) and xI = 1/sqrt(2) + // For numerator: bit_met_num_im_m = abs_psi_rmp + abs_psi_ipm - y0r/sqrt(2) + y0i/sqrt(2) + __m128i bit_met_num_im_m = simde_mm_adds_epi16(abs_psi_rmp, abs_psi_ipm); + bit_met_num_im_m = simde_mm_subs_epi16(bit_met_num_im_m, y0r_over2); + bit_met_num_im_m = simde_mm_adds_epi16(bit_met_num_im_m, y0i_over2); + + // xR = 1/sqrt(2) and xI = -1/sqrt(2) + // For denominator: bit_met_den_im_p = abs_psi_rmm + abs_psi_ipp + y0r/sqrt(2) - y0i/sqrt(2) + __m128i bit_met_den_im_p = simde_mm_adds_epi16(abs_psi_rmm, abs_psi_ipp); + bit_met_den_im_p = simde_mm_adds_epi16(bit_met_den_im_p, y0r_over2); + bit_met_den_im_p = simde_mm_subs_epi16(bit_met_den_im_p, y0i_over2); + + // xR = -1/sqrt(2) and xI = -1/sqrt(2) + // For denominator: bit_met_den_im_m = abs_psi_rpp + abs_psi_imp - y0r/sqrt(2)- y0i/sqrt(2) + __m128i bit_met_den_im_m = simde_mm_adds_epi16(abs_psi_rpp, abs_psi_imp); + bit_met_den_im_m = simde_mm_subs_epi16(bit_met_den_im_m, y0r_over2); + bit_met_den_im_m = simde_mm_subs_epi16(bit_met_den_im_m, y0i_over2); + + /// Compute the LLRs + + // LLR = lambda(c==1) - lambda(c==0) + + __m128i logmax_num_re0 = simde_mm_max_epi16(bit_met_num_re_p, bit_met_num_re_m); // LLR of the first bit: Bit = 1 + __m128i logmax_den_re0 = simde_mm_max_epi16(bit_met_den_re_p, bit_met_den_re_m); // LLR of the first bit: Bit = 0 + __m128i logmax_num_im0 = simde_mm_max_epi16(bit_met_num_im_p, bit_met_num_im_m); // LLR of the second bit: Bit = 1 + __m128i logmax_den_im0 = simde_mm_max_epi16(bit_met_den_im_p, bit_met_den_im_m); // LLR of the second bit: Bit = 0 + + y0r = simde_mm_subs_epi16(logmax_num_re0, logmax_den_re0); // LLR of first bit [L1(1), L1(2), L1(3), L1(4)] + y0i = simde_mm_subs_epi16(logmax_num_im0, logmax_den_im0); // LLR of second bit [L2(1), L2(2), L2(3), L2(4)] + + // [L1(1), L2(1), L1(2), L2(2)] + simde_mm_storeu_si128(&stream0_128i_out[i], simde_mm_unpacklo_epi16(y0r, y0i)); + + // false if only 2 REs remain + if (i < ((length >> 1) - 1)) { + simde_mm_storeu_si128(&stream0_128i_out[i + 1], simde_mm_unpackhi_epi16(y0r, y0i)); + } + } + + _mm_empty(); + _m_empty(); +} + + +void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, + int32_t ***rho, + int16_t **llr_layers, + uint8_t nb_antennas_rx, + uint32_t rb_size, + uint32_t nb_re, + uint8_t symbol, + uint32_t rxdataF_ext_offset, + uint8_t mod_order) +{ + int off = ((rb_size & 1) == 1) ? 4 : 0; + c16_t *rxdataF_comp0 = (c16_t *)&rxdataF_comp[0][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; + c16_t *rxdataF_comp1 = (c16_t *)&rxdataF_comp[nb_antennas_rx][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; + c16_t *llr_layers0 = (c16_t *)&llr_layers[0][rxdataF_ext_offset * mod_order]; + c16_t *llr_layers1 = (c16_t *)&llr_layers[1][rxdataF_ext_offset * mod_order]; + c16_t *rho0 = (c16_t *)&rho[0][1][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; + c16_t *rho1 = (c16_t *)&rho[0][2][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; + + switch (mod_order) { + case 2: + nr_ulsch_qpsk_qpsk(rxdataF_comp0, rxdataF_comp1, llr_layers0, rho0, nb_re); + nr_ulsch_qpsk_qpsk(rxdataF_comp1, rxdataF_comp0, llr_layers1, rho1, nb_re); + break; + case 4: + case 6: + AssertFatal(1 == 0, "LLR computation is not implemented yet for ML with Qm = %d\n", mod_order); + default: + AssertFatal(1 == 0, "nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n", symbol, mod_order); + } +} + +void nr_ulsch_shift_llr(int16_t **llr_layers, uint32_t nb_re, uint32_t rxdataF_ext_offset, uint8_t mod_order, int shift) +{ + __m128i *llr_layers0 = (__m128i *)&llr_layers[0][rxdataF_ext_offset * mod_order]; + __m128i *llr_layers1 = (__m128i *)&llr_layers[1][rxdataF_ext_offset * mod_order]; + + uint8_t mem_offset = ((16 - ((long)llr_layers0)) & 0xF) >> 2; + + if (mem_offset > 0) { + c16_t *llr_layers0_c16 = (c16_t *)&llr_layers[0][rxdataF_ext_offset * mod_order]; + c16_t *llr_layers1_c16 = (c16_t *)&llr_layers[1][rxdataF_ext_offset * mod_order]; + for (int i = 0; i < mem_offset; i++) { + llr_layers0_c16[i] = c16Shift(llr_layers0_c16[i], shift); + llr_layers1_c16[i] = c16Shift(llr_layers1_c16[i], shift); + } + llr_layers0 = (__m128i *)&llr_layers[0][rxdataF_ext_offset * mod_order + (mem_offset << 1)]; + llr_layers1 = (__m128i *)&llr_layers[1][rxdataF_ext_offset * mod_order + (mem_offset << 1)]; + } + + for (int i = 0; i < nb_re >> 2; i++) { + llr_layers0[i] = simde_mm_srai_epi16(llr_layers0[i], shift); + llr_layers1[i] = simde_mm_srai_epi16(llr_layers1[i], shift); + } +} \ No newline at end of file From 46dca7a111282d6c46bdb8f8f06eb9b8213da37d Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 23 Mar 2023 11:00:52 +0000 Subject: [PATCH 08/19] Compute LLR for 16QAM for ML --- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 1 + .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 1 + .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 663 ++++++++++++++++++ 3 files changed, 665 insertions(+) diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 306d44f8f5..2478748688 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -293,6 +293,7 @@ void reset_active_stats(PHY_VARS_gNB *gNB, int frame); void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame); void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, + int32_t **ul_ch_mag, int32_t ***rho, int16_t **llr_layers, uint8_t nb_antennas_rx, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 56e4575f7a..405a73a5fd 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -2177,6 +2177,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, } } else { nr_ulsch_compute_ML_llr(pusch_vars->rxdataF_comp, + pusch_vars->ul_ch_mag0, pusch_vars->rho, pusch_vars->llr_layers, frame_parms->nb_antennas_rx, diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index dc5e117267..924c68a1f4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -718,8 +718,666 @@ void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, c16_t *stream0_out _m_empty(); } +int16_t ones[8] __attribute__((aligned(16))) = {0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; + +// Calculates psi_a = psi_r * a_r + psi_i * a_i +#define prodsum_psi_a_epi16(psi_r, a_r, psi_i, a_i, psi_a) \ + tmp_result = simde_mm_mulhi_epi16(psi_r, a_r); \ + tmp_result = simde_mm_slli_epi16(tmp_result, 1); \ + tmp_result2 = simde_mm_mulhi_epi16(psi_i, a_i); \ + tmp_result2 = simde_mm_slli_epi16(tmp_result2, 1); \ + psi_a = simde_mm_adds_epi16(tmp_result, tmp_result2); + +// Calculate interference magnitude +#define interference_abs_epi16(psi, int_ch_mag, int_mag, c1, c2) \ + tmp_result = simde_mm_cmplt_epi16(psi, int_ch_mag); \ + tmp_result2 = simde_mm_xor_si128(tmp_result, (*(__m128i *)&ones[0])); \ + tmp_result = simde_mm_and_si128(tmp_result, c1); \ + tmp_result2 = simde_mm_and_si128(tmp_result2, c2); \ + int_mag = simde_mm_or_si128(tmp_result, tmp_result2); + +// Calculates a_sq = int_ch_mag * (a_r^2 + a_i^2) * scale_factor +#define square_a_epi16(a_r, a_i, int_ch_mag, scale_factor, a_sq) \ + tmp_result = simde_mm_mulhi_epi16(a_r, a_r); \ + tmp_result = simde_mm_slli_epi16(tmp_result, 1); \ + tmp_result = simde_mm_mulhi_epi16(tmp_result, scale_factor); \ + tmp_result = simde_mm_slli_epi16(tmp_result, 1); \ + tmp_result = simde_mm_mulhi_epi16(tmp_result, int_ch_mag); \ + tmp_result = simde_mm_slli_epi16(tmp_result, 1); \ + tmp_result2 = simde_mm_mulhi_epi16(a_i, a_i); \ + tmp_result2 = simde_mm_slli_epi16(tmp_result2, 1); \ + tmp_result2 = simde_mm_mulhi_epi16(tmp_result2, scale_factor); \ + tmp_result2 = simde_mm_slli_epi16(tmp_result2, 1); \ + tmp_result2 = simde_mm_mulhi_epi16(tmp_result2, int_ch_mag); \ + tmp_result2 = simde_mm_slli_epi16(tmp_result2, 1); \ + a_sq = simde_mm_adds_epi16(tmp_result, tmp_result2); + +__m128i max_epi16(__m128i m0, __m128i m1, __m128i m2, __m128i m3, __m128i m4, __m128i m5, __m128i m6, __m128i m7) +{ + __m128i a0 = simde_mm_max_epi16(m0, m1); + __m128i a1 = simde_mm_max_epi16(m2, m3); + __m128i a2 = simde_mm_max_epi16(m4, m5); + __m128i a3 = simde_mm_max_epi16(m6, m7); + __m128i b0 = simde_mm_max_epi16(a0, a1); + __m128i b1 = simde_mm_max_epi16(a2, a3); + return simde_mm_max_epi16(b0, b1); +} + +/* + * This function computes the LLRs of stream 0 (s_0) in presence of the interfering stream 1 (s_1) assuming that both symbols are + * 16QAM. It can be used for both MU-MIMO interference-aware receiver or for SU-MIMO receivers. + * + * Input: + * stream0_in: MF filter output for 1st stream, i.e., y0' = h0'*y0 + * stream1_in: MF filter output for 2nd stream, i.e., y1' = h1'*y0 + * ch_mag: 2*h0/sqrt(10), [Re0 Im0 Re1 Im1] s.t. Im0=Re0, Im1=Re1, etc + * ch_mag_i: 2*h1/sqrt(10), [Re0 Im0 Re1 Im1] s.t. Im0=Re0, Im1=Re1, etc + * rho01: Channel cross correlation, i.e., rho01 = h0'*h1 + * length: Number of resource elements + * + * Output: + * stream0_out: Output LLRs for 1st stream + */ +void nr_ulsch_qam16_qam16(c16_t *stream0_in, + c16_t *stream1_in, + c16_t *ch_mag, + c16_t *ch_mag_i, + c16_t *stream0_out, + c16_t *rho01, + uint32_t length) +{ + __m128i *rho01_128i = (__m128i *)rho01; + __m128i *stream0_128i_in = (__m128i *)stream0_in; + __m128i *stream1_128i_in = (__m128i *)stream1_in; + __m128i *stream0_128i_out = (__m128i *)stream0_out; + __m128i *ch_mag_128i = (__m128i *)ch_mag; + __m128i *ch_mag_128i_i = (__m128i *)ch_mag_i; + + __m128i ONE_OVER_SQRT_10 = simde_mm_set1_epi16(20724); // round(1/sqrt(10)*2^16) + __m128i ONE_OVER_SQRT_10_Q15 = simde_mm_set1_epi16(10362); // round(1/sqrt(10)*2^15) + __m128i THREE_OVER_SQRT_10 = simde_mm_set1_epi16(31086); // round(3/sqrt(10)*2^15) + __m128i SQRT_10_OVER_FOUR = simde_mm_set1_epi16(25905); // round(sqrt(10)/4*2^15) + __m128i ONE_OVER_TWO_SQRT_10 = simde_mm_set1_epi16(10362); // round(1/2/sqrt(10)*2^16) + __m128i NINE_OVER_TWO_SQRT_10 = simde_mm_set1_epi16(23315); // round(9/2/sqrt(10)*2^14) + __m128i ch_mag_des, ch_mag_int; + __m128i y0r_over_sqrt10; + __m128i y0i_over_sqrt10; + __m128i y0r_three_over_sqrt10; + __m128i y0i_three_over_sqrt10; + __m128i ch_mag_over_10; + __m128i ch_mag_over_2; + __m128i ch_mag_9_over_10; + + __m128i xmm0 __attribute__((aligned(16))); + __m128i xmm1 __attribute__((aligned(16))); + __m128i xmm2 __attribute__((aligned(16))); + __m128i xmm3 __attribute__((aligned(16))); + __m128i xmm4 __attribute__((aligned(16))); + __m128i xmm5 __attribute__((aligned(16))); + __m128i xmm6 __attribute__((aligned(16))); + __m128i xmm7 __attribute__((aligned(16))); + + __m128i rho_rpi __attribute__((aligned(16))); + __m128i rho_rmi __attribute__((aligned(16))); + __m128i rho_rpi_1_1 __attribute__((aligned(16))); + __m128i rho_rpi_1_3 __attribute__((aligned(16))); + __m128i rho_rpi_3_1 __attribute__((aligned(16))); + __m128i rho_rpi_3_3 __attribute__((aligned(16))); + __m128i rho_rmi_1_1 __attribute__((aligned(16))); + __m128i rho_rmi_1_3 __attribute__((aligned(16))); + __m128i rho_rmi_3_1 __attribute__((aligned(16))); + __m128i rho_rmi_3_3 __attribute__((aligned(16))); + + __m128i psi_r_m3_m3 __attribute__((aligned(16))); + __m128i psi_r_m3_m1 __attribute__((aligned(16))); + __m128i psi_r_m3_p1 __attribute__((aligned(16))); + __m128i psi_r_m3_p3 __attribute__((aligned(16))); + __m128i psi_r_m1_m3 __attribute__((aligned(16))); + __m128i psi_r_m1_m1 __attribute__((aligned(16))); + __m128i psi_r_m1_p1 __attribute__((aligned(16))); + __m128i psi_r_m1_p3 __attribute__((aligned(16))); + __m128i psi_r_p1_m3 __attribute__((aligned(16))); + __m128i psi_r_p1_m1 __attribute__((aligned(16))); + __m128i psi_r_p1_p1 __attribute__((aligned(16))); + __m128i psi_r_p1_p3 __attribute__((aligned(16))); + __m128i psi_r_p3_m3 __attribute__((aligned(16))); + __m128i psi_r_p3_m1 __attribute__((aligned(16))); + __m128i psi_r_p3_p1 __attribute__((aligned(16))); + __m128i psi_r_p3_p3 __attribute__((aligned(16))); + + __m128i psi_i_m3_m3 __attribute__((aligned(16))); + __m128i psi_i_m3_m1 __attribute__((aligned(16))); + __m128i psi_i_m3_p1 __attribute__((aligned(16))); + __m128i psi_i_m3_p3 __attribute__((aligned(16))); + __m128i psi_i_m1_m3 __attribute__((aligned(16))); + __m128i psi_i_m1_m1 __attribute__((aligned(16))); + __m128i psi_i_m1_p1 __attribute__((aligned(16))); + __m128i psi_i_m1_p3 __attribute__((aligned(16))); + __m128i psi_i_p1_m3 __attribute__((aligned(16))); + __m128i psi_i_p1_m1 __attribute__((aligned(16))); + __m128i psi_i_p1_p1 __attribute__((aligned(16))); + __m128i psi_i_p1_p3 __attribute__((aligned(16))); + __m128i psi_i_p3_m3 __attribute__((aligned(16))); + __m128i psi_i_p3_m1 __attribute__((aligned(16))); + __m128i psi_i_p3_p1 __attribute__((aligned(16))); + __m128i psi_i_p3_p3 __attribute__((aligned(16))); + + __m128i a_r_m3_m3 __attribute__((aligned(16))); + __m128i a_r_m3_m1 __attribute__((aligned(16))); + __m128i a_r_m3_p1 __attribute__((aligned(16))); + __m128i a_r_m3_p3 __attribute__((aligned(16))); + __m128i a_r_m1_m3 __attribute__((aligned(16))); + __m128i a_r_m1_m1 __attribute__((aligned(16))); + __m128i a_r_m1_p1 __attribute__((aligned(16))); + __m128i a_r_m1_p3 __attribute__((aligned(16))); + __m128i a_r_p1_m3 __attribute__((aligned(16))); + __m128i a_r_p1_m1 __attribute__((aligned(16))); + __m128i a_r_p1_p1 __attribute__((aligned(16))); + __m128i a_r_p1_p3 __attribute__((aligned(16))); + __m128i a_r_p3_m3 __attribute__((aligned(16))); + __m128i a_r_p3_m1 __attribute__((aligned(16))); + __m128i a_r_p3_p1 __attribute__((aligned(16))); + __m128i a_r_p3_p3 __attribute__((aligned(16))); + + __m128i a_i_m3_m3 __attribute__((aligned(16))); + __m128i a_i_m3_m1 __attribute__((aligned(16))); + __m128i a_i_m3_p1 __attribute__((aligned(16))); + __m128i a_i_m3_p3 __attribute__((aligned(16))); + __m128i a_i_m1_m3 __attribute__((aligned(16))); + __m128i a_i_m1_m1 __attribute__((aligned(16))); + __m128i a_i_m1_p1 __attribute__((aligned(16))); + __m128i a_i_m1_p3 __attribute__((aligned(16))); + __m128i a_i_p1_m3 __attribute__((aligned(16))); + __m128i a_i_p1_m1 __attribute__((aligned(16))); + __m128i a_i_p1_p1 __attribute__((aligned(16))); + __m128i a_i_p1_p3 __attribute__((aligned(16))); + __m128i a_i_p3_m3 __attribute__((aligned(16))); + __m128i a_i_p3_m1 __attribute__((aligned(16))); + __m128i a_i_p3_p1 __attribute__((aligned(16))); + __m128i a_i_p3_p3 __attribute__((aligned(16))); + + __m128i psi_a_m3_m3 __attribute__((aligned(16))); + __m128i psi_a_m3_m1 __attribute__((aligned(16))); + __m128i psi_a_m3_p1 __attribute__((aligned(16))); + __m128i psi_a_m3_p3 __attribute__((aligned(16))); + __m128i psi_a_m1_m3 __attribute__((aligned(16))); + __m128i psi_a_m1_m1 __attribute__((aligned(16))); + __m128i psi_a_m1_p1 __attribute__((aligned(16))); + __m128i psi_a_m1_p3 __attribute__((aligned(16))); + __m128i psi_a_p1_m3 __attribute__((aligned(16))); + __m128i psi_a_p1_m1 __attribute__((aligned(16))); + __m128i psi_a_p1_p1 __attribute__((aligned(16))); + __m128i psi_a_p1_p3 __attribute__((aligned(16))); + __m128i psi_a_p3_m3 __attribute__((aligned(16))); + __m128i psi_a_p3_m1 __attribute__((aligned(16))); + __m128i psi_a_p3_p1 __attribute__((aligned(16))); + __m128i psi_a_p3_p3 __attribute__((aligned(16))); + + __m128i a_sq_m3_m3 __attribute__((aligned(16))); + __m128i a_sq_m3_m1 __attribute__((aligned(16))); + __m128i a_sq_m3_p1 __attribute__((aligned(16))); + __m128i a_sq_m3_p3 __attribute__((aligned(16))); + __m128i a_sq_m1_m3 __attribute__((aligned(16))); + __m128i a_sq_m1_m1 __attribute__((aligned(16))); + __m128i a_sq_m1_p1 __attribute__((aligned(16))); + __m128i a_sq_m1_p3 __attribute__((aligned(16))); + __m128i a_sq_p1_m3 __attribute__((aligned(16))); + __m128i a_sq_p1_m1 __attribute__((aligned(16))); + __m128i a_sq_p1_p1 __attribute__((aligned(16))); + __m128i a_sq_p1_p3 __attribute__((aligned(16))); + __m128i a_sq_p3_m3 __attribute__((aligned(16))); + __m128i a_sq_p3_m1 __attribute__((aligned(16))); + __m128i a_sq_p3_p1 __attribute__((aligned(16))); + __m128i a_sq_p3_p3 __attribute__((aligned(16))); + + __m128i y0_p_1_1 __attribute__((aligned(16))); + __m128i y0_p_1_3 __attribute__((aligned(16))); + __m128i y0_p_3_1 __attribute__((aligned(16))); + __m128i y0_p_3_3 __attribute__((aligned(16))); + __m128i y0_m_1_1 __attribute__((aligned(16))); + __m128i y0_m_1_3 __attribute__((aligned(16))); + __m128i y0_m_3_1 __attribute__((aligned(16))); + __m128i y0_m_3_3 __attribute__((aligned(16))); + + __m128i y0r __attribute__((aligned(16))); + __m128i y0i __attribute__((aligned(16))); + __m128i y1r __attribute__((aligned(16))); + __m128i y1i __attribute__((aligned(16))); + + __m128i tmp_result __attribute__((aligned(16))); + __m128i tmp_result2 __attribute__((aligned(16))); + + // In one iteration, we deal with 8 REs + for (int i = 0; i < length >> 2; i += 2) { + + // Get rho + xmm0 = rho01_128i[i]; + xmm1 = rho01_128i[i + 1]; + xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + // xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + // xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) + xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) + rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) + + // Compute the different rhos + rho_rpi_1_1 = simde_mm_mulhi_epi16(rho_rpi, ONE_OVER_SQRT_10); + rho_rmi_1_1 = simde_mm_mulhi_epi16(rho_rmi, ONE_OVER_SQRT_10); + rho_rpi_3_3 = simde_mm_mulhi_epi16(rho_rpi, THREE_OVER_SQRT_10); + rho_rmi_3_3 = simde_mm_mulhi_epi16(rho_rmi, THREE_OVER_SQRT_10); + rho_rpi_3_3 = simde_mm_slli_epi16(rho_rpi_3_3, 1); + rho_rmi_3_3 = simde_mm_slli_epi16(rho_rmi_3_3, 1); + + xmm4 = simde_mm_mulhi_epi16(xmm2, ONE_OVER_SQRT_10); // Re(rho) + xmm5 = simde_mm_mulhi_epi16(xmm3, THREE_OVER_SQRT_10); // Im(rho) + xmm5 = simde_mm_slli_epi16(xmm5, 1); + + rho_rpi_1_3 = simde_mm_adds_epi16(xmm4, xmm5); + rho_rmi_1_3 = simde_mm_subs_epi16(xmm4, xmm5); + + xmm6 = simde_mm_mulhi_epi16(xmm2, THREE_OVER_SQRT_10); // Re(rho) + xmm7 = simde_mm_mulhi_epi16(xmm3, ONE_OVER_SQRT_10); // Im(rho) + xmm6 = simde_mm_slli_epi16(xmm6, 1); + + rho_rpi_3_1 = simde_mm_adds_epi16(xmm6, xmm7); + rho_rmi_3_1 = simde_mm_subs_epi16(xmm6, xmm7); + + // Rearrange interfering MF output + xmm0 = stream1_128i_in[i]; + xmm1 = stream1_128i_in[i + 1]; + xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + // xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + // xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] + y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + + xmm0 = simde_mm_setzero_si128(); // ZERO + xmm2 = simde_mm_subs_epi16(rho_rpi_1_1, y1r); // = [Re(rho)+ Im(rho)]/sqrt(10) - y1r + psi_r_p1_p1 = simde_mm_abs_epi16(xmm2); // = |[Re(rho)+ Im(rho)]/sqrt(10) - y1r| + + xmm2 = simde_mm_subs_epi16(rho_rmi_1_1, y1r); + psi_r_p1_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_1_1, y1i); + psi_i_p1_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_1_3, y1r); + psi_r_p1_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_1_3, y1r); + psi_r_p1_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_3_1, y1i); + psi_i_p1_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_3_1, y1r); + psi_r_p3_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_3_1, y1r); + psi_r_p3_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_1_3, y1i); + psi_i_p3_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_3_3, y1r); + psi_r_p3_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_3_3, y1r); + psi_r_p3_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rmi_3_3, y1i); + psi_i_p3_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_1_1, y1i); + psi_i_m1_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_3_1, y1i); + psi_i_m1_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_1_3, y1i); + psi_i_m3_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_subs_epi16(rho_rpi_3_3, y1i); + psi_i_m3_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_1_1, y1i); + psi_i_p1_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_3_1, y1i); + psi_i_p1_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_1_3, y1i); + psi_i_p3_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_3_3, y1i); + psi_i_p3_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_1_1, y1r); + psi_r_m1_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_1_3, y1r); + psi_r_m1_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_3_1, y1r); + psi_r_m3_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(rho_rpi_3_3, y1r); + psi_r_m3_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1r, rho_rmi_1_1); + psi_r_m1_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1r, rho_rmi_1_3); + psi_r_m1_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1i, rho_rmi_1_1); + psi_i_m1_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1i, rho_rmi_3_1); + psi_i_m1_m3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1r, rho_rmi_3_1); + psi_r_m3_p1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1r, rho_rmi_3_3); + psi_r_m3_p3 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1i, rho_rmi_1_3); + psi_i_m3_m1 = simde_mm_abs_epi16(xmm2); + xmm2 = simde_mm_adds_epi16(y1i, rho_rmi_3_3); + psi_i_m3_m3 = simde_mm_abs_epi16(xmm2); + + // Rearrange desired MF output + xmm0 = stream0_128i_in[i]; + xmm1 = stream0_128i_in[i + 1]; + xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + // xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + // xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] + y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + + // Rearrange desired channel magnitudes + xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) + xmm3 = ch_mag_128i[i + 1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) + xmm2 = simde_mm_shufflelo_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm2 = simde_mm_shufflehi_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm2 = simde_mm_shuffle_epi32(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm3 = simde_mm_shufflelo_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm3 = simde_mm_shufflehi_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm3 = simde_mm_shuffle_epi32(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + ch_mag_des = simde_mm_unpacklo_epi64(xmm2, xmm3); // = [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) + + // Rearrange interfering channel magnitudes + xmm2 = ch_mag_128i_i[i]; + xmm3 = ch_mag_128i_i[i + 1]; + + xmm2 = simde_mm_shufflelo_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm2 = simde_mm_shufflehi_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm2 = simde_mm_shuffle_epi32(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm3 = simde_mm_shufflelo_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm3 = simde_mm_shufflehi_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + xmm3 = simde_mm_shuffle_epi32(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + ch_mag_int = simde_mm_unpacklo_epi64(xmm2, xmm3); + + // Scale MF output of desired signal + y0r_over_sqrt10 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_10); + y0i_over_sqrt10 = simde_mm_mulhi_epi16(y0i, ONE_OVER_SQRT_10); + y0r_three_over_sqrt10 = simde_mm_mulhi_epi16(y0r, THREE_OVER_SQRT_10); + y0i_three_over_sqrt10 = simde_mm_mulhi_epi16(y0i, THREE_OVER_SQRT_10); + y0r_three_over_sqrt10 = simde_mm_slli_epi16(y0r_three_over_sqrt10, 1); + y0i_three_over_sqrt10 = simde_mm_slli_epi16(y0i_three_over_sqrt10, 1); + + // Compute necessary combination of required terms + y0_p_1_1 = simde_mm_adds_epi16(y0r_over_sqrt10, y0i_over_sqrt10); + y0_m_1_1 = simde_mm_subs_epi16(y0r_over_sqrt10, y0i_over_sqrt10); + + y0_p_1_3 = simde_mm_adds_epi16(y0r_over_sqrt10, y0i_three_over_sqrt10); + y0_m_1_3 = simde_mm_subs_epi16(y0r_over_sqrt10, y0i_three_over_sqrt10); + + y0_p_3_1 = simde_mm_adds_epi16(y0r_three_over_sqrt10, y0i_over_sqrt10); + y0_m_3_1 = simde_mm_subs_epi16(y0r_three_over_sqrt10, y0i_over_sqrt10); + + y0_p_3_3 = simde_mm_adds_epi16(y0r_three_over_sqrt10, y0i_three_over_sqrt10); + y0_m_3_3 = simde_mm_subs_epi16(y0r_three_over_sqrt10, y0i_three_over_sqrt10); + + // Compute optimal interfering symbol magnitude + interference_abs_epi16(psi_r_p1_p1, ch_mag_int, a_r_p1_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p1_p1, ch_mag_int, a_i_p1_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p1_p3, ch_mag_int, a_r_p1_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p1_p3, ch_mag_int, a_i_p1_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p1_m1, ch_mag_int, a_r_p1_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p1_m1, ch_mag_int, a_i_p1_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p1_m3, ch_mag_int, a_r_p1_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p1_m3, ch_mag_int, a_i_p1_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p3_p1, ch_mag_int, a_r_p3_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p3_p1, ch_mag_int, a_i_p3_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p3_p3, ch_mag_int, a_r_p3_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p3_p3, ch_mag_int, a_i_p3_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p3_m1, ch_mag_int, a_r_p3_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p3_m1, ch_mag_int, a_i_p3_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_p3_m3, ch_mag_int, a_r_p3_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_p3_m3, ch_mag_int, a_i_p3_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m1_p1, ch_mag_int, a_r_m1_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m1_p1, ch_mag_int, a_i_m1_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m1_p3, ch_mag_int, a_r_m1_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m1_p3, ch_mag_int, a_i_m1_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m1_m1, ch_mag_int, a_r_m1_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m1_m1, ch_mag_int, a_i_m1_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m1_m3, ch_mag_int, a_r_m1_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m1_m3, ch_mag_int, a_i_m1_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m3_p1, ch_mag_int, a_r_m3_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m3_p1, ch_mag_int, a_i_m3_p1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m3_p3, ch_mag_int, a_r_m3_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m3_p3, ch_mag_int, a_i_m3_p3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m3_m1, ch_mag_int, a_r_m3_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m3_m1, ch_mag_int, a_i_m3_m1, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_r_m3_m3, ch_mag_int, a_r_m3_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + interference_abs_epi16(psi_i_m3_m3, ch_mag_int, a_i_m3_m3, ONE_OVER_SQRT_10_Q15, THREE_OVER_SQRT_10); + + // Calculation of groups of two terms in the bit metric involving product of psi and interference magnitude + prodsum_psi_a_epi16(psi_r_p1_p1, a_r_p1_p1, psi_i_p1_p1, a_i_p1_p1, psi_a_p1_p1); + prodsum_psi_a_epi16(psi_r_p1_p3, a_r_p1_p3, psi_i_p1_p3, a_i_p1_p3, psi_a_p1_p3); + prodsum_psi_a_epi16(psi_r_p3_p1, a_r_p3_p1, psi_i_p3_p1, a_i_p3_p1, psi_a_p3_p1); + prodsum_psi_a_epi16(psi_r_p3_p3, a_r_p3_p3, psi_i_p3_p3, a_i_p3_p3, psi_a_p3_p3); + prodsum_psi_a_epi16(psi_r_p1_m1, a_r_p1_m1, psi_i_p1_m1, a_i_p1_m1, psi_a_p1_m1); + prodsum_psi_a_epi16(psi_r_p1_m3, a_r_p1_m3, psi_i_p1_m3, a_i_p1_m3, psi_a_p1_m3); + prodsum_psi_a_epi16(psi_r_p3_m1, a_r_p3_m1, psi_i_p3_m1, a_i_p3_m1, psi_a_p3_m1); + prodsum_psi_a_epi16(psi_r_p3_m3, a_r_p3_m3, psi_i_p3_m3, a_i_p3_m3, psi_a_p3_m3); + prodsum_psi_a_epi16(psi_r_m1_p1, a_r_m1_p1, psi_i_m1_p1, a_i_m1_p1, psi_a_m1_p1); + prodsum_psi_a_epi16(psi_r_m1_p3, a_r_m1_p3, psi_i_m1_p3, a_i_m1_p3, psi_a_m1_p3); + prodsum_psi_a_epi16(psi_r_m3_p1, a_r_m3_p1, psi_i_m3_p1, a_i_m3_p1, psi_a_m3_p1); + prodsum_psi_a_epi16(psi_r_m3_p3, a_r_m3_p3, psi_i_m3_p3, a_i_m3_p3, psi_a_m3_p3); + prodsum_psi_a_epi16(psi_r_m1_m1, a_r_m1_m1, psi_i_m1_m1, a_i_m1_m1, psi_a_m1_m1); + prodsum_psi_a_epi16(psi_r_m1_m3, a_r_m1_m3, psi_i_m1_m3, a_i_m1_m3, psi_a_m1_m3); + prodsum_psi_a_epi16(psi_r_m3_m1, a_r_m3_m1, psi_i_m3_m1, a_i_m3_m1, psi_a_m3_m1); + prodsum_psi_a_epi16(psi_r_m3_m3, a_r_m3_m3, psi_i_m3_m3, a_i_m3_m3, psi_a_m3_m3); + + // squared interference magnitude times int. ch. power + square_a_epi16(a_r_p1_p1, a_i_p1_p1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p1_p1); + square_a_epi16(a_r_p1_p3, a_i_p1_p3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p1_p3); + square_a_epi16(a_r_p3_p1, a_i_p3_p1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p3_p1); + square_a_epi16(a_r_p3_p3, a_i_p3_p3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p3_p3); + square_a_epi16(a_r_p1_m1, a_i_p1_m1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p1_m1); + square_a_epi16(a_r_p1_m3, a_i_p1_m3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p1_m3); + square_a_epi16(a_r_p3_m1, a_i_p3_m1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p3_m1); + square_a_epi16(a_r_p3_m3, a_i_p3_m3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_p3_m3); + square_a_epi16(a_r_m1_p1, a_i_m1_p1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m1_p1); + square_a_epi16(a_r_m1_p3, a_i_m1_p3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m1_p3); + square_a_epi16(a_r_m3_p1, a_i_m3_p1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m3_p1); + square_a_epi16(a_r_m3_p3, a_i_m3_p3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m3_p3); + square_a_epi16(a_r_m1_m1, a_i_m1_m1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m1_m1); + square_a_epi16(a_r_m1_m3, a_i_m1_m3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m1_m3); + square_a_epi16(a_r_m3_m1, a_i_m3_m1, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m3_m1); + square_a_epi16(a_r_m3_m3, a_i_m3_m3, ch_mag_int, SQRT_10_OVER_FOUR, a_sq_m3_m3); + + // Computing different multiples of channel norms + ch_mag_over_10 = simde_mm_mulhi_epi16(ch_mag_des, ONE_OVER_TWO_SQRT_10); + ch_mag_over_2 = simde_mm_mulhi_epi16(ch_mag_des, SQRT_10_OVER_FOUR); + ch_mag_over_2 = simde_mm_slli_epi16(ch_mag_over_2, 1); + ch_mag_9_over_10 = simde_mm_mulhi_epi16(ch_mag_des, NINE_OVER_TWO_SQRT_10); + ch_mag_9_over_10 = simde_mm_slli_epi16(ch_mag_9_over_10, 2); + + /// Compute bit metrics (lambda) + + __m128i bit_met_p1_p1 = simde_mm_subs_epi16(psi_a_p1_p1, a_sq_p1_p1); + bit_met_p1_p1 = simde_mm_adds_epi16(bit_met_p1_p1, y0_p_1_1); + bit_met_p1_p1 = simde_mm_subs_epi16(bit_met_p1_p1, ch_mag_over_10); + + __m128i bit_met_p1_p3 = simde_mm_subs_epi16(psi_a_p1_p3, a_sq_p1_p3); + bit_met_p1_p3 = simde_mm_adds_epi16(bit_met_p1_p3, y0_p_1_3); + bit_met_p1_p3 = simde_mm_subs_epi16(bit_met_p1_p3, ch_mag_over_2); + + __m128i bit_met_p1_m1 = simde_mm_subs_epi16(psi_a_p1_m1, a_sq_p1_m1); + bit_met_p1_m1 = simde_mm_adds_epi16(bit_met_p1_m1, y0_m_1_1); + bit_met_p1_m1 = simde_mm_subs_epi16(bit_met_p1_m1, ch_mag_over_10); + + __m128i bit_met_p1_m3 = simde_mm_subs_epi16(psi_a_p1_m3, a_sq_p1_m3); + bit_met_p1_m3 = simde_mm_adds_epi16(bit_met_p1_m3, y0_m_1_3); + bit_met_p1_m3 = simde_mm_subs_epi16(bit_met_p1_m3, ch_mag_over_2); + + __m128i bit_met_p3_p1 = simde_mm_subs_epi16(psi_a_p3_p1, a_sq_p3_p1); + bit_met_p3_p1 = simde_mm_adds_epi16(bit_met_p3_p1, y0_p_3_1); + bit_met_p3_p1 = simde_mm_subs_epi16(bit_met_p3_p1, ch_mag_over_2); + + __m128i bit_met_p3_p3 = simde_mm_subs_epi16(psi_a_p3_p3, a_sq_p3_p3); + bit_met_p3_p3 = simde_mm_adds_epi16(bit_met_p3_p3, y0_p_3_3); + bit_met_p3_p3 = simde_mm_subs_epi16(bit_met_p3_p3, ch_mag_9_over_10); + + __m128i bit_met_p3_m1 = simde_mm_subs_epi16(psi_a_p3_m1, a_sq_p3_m1); + bit_met_p3_m1 = simde_mm_adds_epi16(bit_met_p3_m1, y0_m_3_1); + bit_met_p3_m1 = simde_mm_subs_epi16(bit_met_p3_m1, ch_mag_over_2); + + __m128i bit_met_p3_m3 = simde_mm_subs_epi16(psi_a_p3_m3, a_sq_p3_m3); + bit_met_p3_m3 = simde_mm_adds_epi16(bit_met_p3_m3, y0_m_3_3); + bit_met_p3_m3 = simde_mm_subs_epi16(bit_met_p3_m3, ch_mag_9_over_10); + + __m128i bit_met_m1_p1 = simde_mm_subs_epi16(psi_a_m1_p1, a_sq_m1_p1); + bit_met_m1_p1 = simde_mm_subs_epi16(bit_met_m1_p1, y0_m_1_1); + bit_met_m1_p1 = simde_mm_subs_epi16(bit_met_m1_p1, ch_mag_over_10); + + __m128i bit_met_m1_p3 = simde_mm_subs_epi16(psi_a_m1_p3, a_sq_m1_p3); + bit_met_m1_p3 = simde_mm_subs_epi16(bit_met_m1_p3, y0_m_1_3); + bit_met_m1_p3 = simde_mm_subs_epi16(bit_met_m1_p3, ch_mag_over_2); + + __m128i bit_met_m1_m1 = simde_mm_subs_epi16(psi_a_m1_m1, a_sq_m1_m1); + bit_met_m1_m1 = simde_mm_subs_epi16(bit_met_m1_m1, y0_p_1_1); + bit_met_m1_m1 = simde_mm_subs_epi16(bit_met_m1_m1, ch_mag_over_10); + + __m128i bit_met_m1_m3 = simde_mm_subs_epi16(psi_a_m1_m3, a_sq_m1_m3); + bit_met_m1_m3 = simde_mm_subs_epi16(bit_met_m1_m3, y0_p_1_3); + bit_met_m1_m3 = simde_mm_subs_epi16(bit_met_m1_m3, ch_mag_over_2); + + __m128i bit_met_m3_p1 = simde_mm_subs_epi16(psi_a_m3_p1, a_sq_m3_p1); + bit_met_m3_p1 = simde_mm_subs_epi16(bit_met_m3_p1, y0_m_3_1); + bit_met_m3_p1 = simde_mm_subs_epi16(bit_met_m3_p1, ch_mag_over_2); + + __m128i bit_met_m3_p3 = simde_mm_subs_epi16(psi_a_m3_p3, a_sq_m3_p3); + bit_met_m3_p3 = simde_mm_subs_epi16(bit_met_m3_p3, y0_m_3_3); + bit_met_m3_p3 = simde_mm_subs_epi16(bit_met_m3_p3, ch_mag_9_over_10); + + __m128i bit_met_m3_m1 = simde_mm_subs_epi16(psi_a_m3_m1, a_sq_m3_m1); + bit_met_m3_m1 = simde_mm_subs_epi16(bit_met_m3_m1, y0_p_3_1); + bit_met_m3_m1 = simde_mm_subs_epi16(bit_met_m3_m1, ch_mag_over_2); + + __m128i bit_met_m3_m3 = simde_mm_subs_epi16(psi_a_m3_m3, a_sq_m3_m3); + bit_met_m3_m3 = simde_mm_subs_epi16(bit_met_m3_m3, y0_p_3_3); + bit_met_m3_m3 = simde_mm_subs_epi16(bit_met_m3_m3, ch_mag_9_over_10); + + /// Compute the LLRs + + // LLR = lambda(c==1) - lambda(c==0) + + // LLR of the first bit: Bit = 1 + __m128i logmax_num_re0 = max_epi16(bit_met_m1_p1, + bit_met_m1_p3, + bit_met_m1_m1, + bit_met_m1_m3, + bit_met_m3_p1, + bit_met_m3_p3, + bit_met_m3_m1, + bit_met_m3_m3); + + // LLR of the first bit: Bit = 0 + __m128i logmax_den_re0 = max_epi16(bit_met_p1_p1, + bit_met_p1_p3, + bit_met_p1_m1, + bit_met_p1_m3, + bit_met_p3_p1, + bit_met_p3_p3, + bit_met_p3_m1, + bit_met_p3_m3); + + // LLR of the second bit: Bit = 1 + __m128i logmax_num_re1 = max_epi16(bit_met_p1_m1, + bit_met_p3_m1, + bit_met_m1_m1, + bit_met_m3_m1, + bit_met_p1_m3, + bit_met_p3_m3, + bit_met_m1_m3, + bit_met_m3_m3); + + // LLR of the second bit: Bit = 0 + __m128i logmax_den_re1 = max_epi16(bit_met_p1_p1, + bit_met_p3_p1, + bit_met_m1_p1, + bit_met_m3_p1, + bit_met_p1_p3, + bit_met_p3_p3, + bit_met_m1_p3, + bit_met_m3_p3); + + // LLR of the third bit: Bit = 1 + __m128i logmax_num_im0 = max_epi16(bit_met_m3_p1, + bit_met_m3_p3, + bit_met_m3_m1, + bit_met_m3_m3, + bit_met_p3_p1, + bit_met_p3_p3, + bit_met_p3_m1, + bit_met_p3_m3); + + // LLR of the third bit: Bit = 0 + __m128i logmax_den_im0 = max_epi16(bit_met_m1_p1, + bit_met_m1_p3, + bit_met_m1_m1, + bit_met_m1_m3, + bit_met_p1_p1, + bit_met_p1_p3, + bit_met_p1_m1, + bit_met_p1_m3); + + // LLR of the fourth bit: Bit = 1 + __m128i logmax_num_im1 = max_epi16(bit_met_p1_m3, + bit_met_p3_m3, + bit_met_m1_m3, + bit_met_m3_m3, + bit_met_p1_p3, + bit_met_p3_p3, + bit_met_m1_p3, + bit_met_m3_p3); + + // LLR of the fourth bit: Bit = 0 + __m128i logmax_den_im1 = max_epi16(bit_met_p1_m1, + bit_met_p3_m1, + bit_met_m1_m1, + bit_met_m3_m1, + bit_met_p1_p1, + bit_met_p3_p1, + bit_met_m1_p1, + bit_met_m3_p1); + + y0r = simde_mm_subs_epi16(logmax_den_re0, logmax_num_re0); // LLR of first bit [L1(1), L1(2), L1(3), L1(4), L1(5), L1(6), L1(7), L1(8)] + y1r = simde_mm_subs_epi16(logmax_den_re1, logmax_num_re1); // LLR of second bit [L2(1), L2(2), L2(3), L2(4), L2(5), L2(6), L2(7), L2(8)] + y0i = simde_mm_subs_epi16(logmax_den_im0, logmax_num_im0); // LLR of third bit [L3(1), L3(2), L3(3), L3(4), L3(5), L3(6), L3(7), L3(8)] + y1i = simde_mm_subs_epi16(logmax_den_im1, logmax_num_im1); // LLR of fourth bit [L4(1), L4(2), L4(3), L4(4), L4(5), L4(6), L4(7), L4(8)] + + // Pack LLRs in output + xmm0 = simde_mm_unpacklo_epi16(y0r, y1r); // [L1(1), L2(1), L1(2), L2(2), L1(3), L2(3), L1(4), L2(4)] + xmm1 = simde_mm_unpackhi_epi16(y0r, y1r); // [L1(5), L2(5), L1(6), L2(6), L1(7), L2(7), L1(8), L2(8)] + xmm2 = simde_mm_unpacklo_epi16(y0i, y1i); // [L3(1), L4(1), L3(2), L4(2), L3(3), L4(3), L3(4), L4(4)] + xmm3 = simde_mm_unpackhi_epi16(y0i, y1i); // [L3(5), L4(5), L3(6), L4(6), L3(7), L4(7), L3(8), L4(8)] + stream0_128i_out[2 * i + 0] = simde_mm_unpacklo_epi32(xmm0, xmm2); // 8 LLRs, 2 REs + stream0_128i_out[2 * i + 1] = simde_mm_unpackhi_epi32(xmm0, xmm2); // 8 LLRs, 2 REs + stream0_128i_out[2 * i + 2] = simde_mm_unpacklo_epi32(xmm1, xmm3); // 8 LLRs, 2 REs + stream0_128i_out[2 * i + 3] = simde_mm_unpackhi_epi32(xmm1, xmm3); // 8 LLRs, 2 REs + } + + _mm_empty(); + _m_empty(); +} void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, + int32_t **ul_ch_mag, int32_t ***rho, int16_t **llr_layers, uint8_t nb_antennas_rx, @@ -732,6 +1390,8 @@ void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, int off = ((rb_size & 1) == 1) ? 4 : 0; c16_t *rxdataF_comp0 = (c16_t *)&rxdataF_comp[0][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; c16_t *rxdataF_comp1 = (c16_t *)&rxdataF_comp[nb_antennas_rx][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; + c16_t *ul_ch_mag0 = (c16_t *)&ul_ch_mag[0][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; + c16_t *ul_ch_mag1 = (c16_t *)&ul_ch_mag[nb_antennas_rx][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; c16_t *llr_layers0 = (c16_t *)&llr_layers[0][rxdataF_ext_offset * mod_order]; c16_t *llr_layers1 = (c16_t *)&llr_layers[1][rxdataF_ext_offset * mod_order]; c16_t *rho0 = (c16_t *)&rho[0][1][symbol * (off + (rb_size * NR_NB_SC_PER_RB))]; @@ -743,6 +1403,9 @@ void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, nr_ulsch_qpsk_qpsk(rxdataF_comp1, rxdataF_comp0, llr_layers1, rho1, nb_re); break; case 4: + nr_ulsch_qam16_qam16(rxdataF_comp0, rxdataF_comp1, ul_ch_mag0, ul_ch_mag1, llr_layers0, rho0, nb_re); + nr_ulsch_qam16_qam16(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re); + break; case 6: AssertFatal(1 == 0, "LLR computation is not implemented yet for ML with Qm = %d\n", mod_order); default: From 8a820db22f449ef6ca6fc6d613fba2a68368dffd Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 20 Apr 2023 19:06:22 +0100 Subject: [PATCH 09/19] Compute LLR for 64QAM for ML --- .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 2628 ++++++++++++++++- 1 file changed, 2627 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 924c68a1f4..0ecadd6646 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -1376,6 +1376,2630 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, _m_empty(); } +static const int16_t ones256[16] __attribute__((aligned(32))) = {0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff, + 0xffff}; + +/// Auxiliary Makros + +// calculate interference magnitude +// tmp_result = ones in shorts corr. to interval 2<=x<=4, tmp_result2 interval < 2, tmp_result3 interval 46 +#define interference_abs_64qam_epi16_256(psi, int_ch_mag, int_two_ch_mag, int_three_ch_mag, a, c1, c3, c5, c7) \ + tmp_result = simde_mm256_cmpgt_epi16(int_two_ch_mag, psi); \ + tmp_result3 = simde_mm256_xor_si256(tmp_result, (*(__m256i *)&ones256[0])); \ + tmp_result2 = simde_mm256_cmpgt_epi16(int_ch_mag, psi); \ + tmp_result = simde_mm256_xor_si256(tmp_result, tmp_result2); \ + tmp_result4 = simde_mm256_cmpgt_epi16(psi, int_three_ch_mag); \ + tmp_result3 = simde_mm256_xor_si256(tmp_result3, tmp_result4); \ + tmp_result = simde_mm256_and_si256(tmp_result, c3); \ + tmp_result2 = simde_mm256_and_si256(tmp_result2, c1); \ + tmp_result3 = simde_mm256_and_si256(tmp_result3, c5); \ + tmp_result4 = simde_mm256_and_si256(tmp_result4, c7); \ + tmp_result = simde_mm256_or_si256(tmp_result, tmp_result2); \ + tmp_result3 = simde_mm256_or_si256(tmp_result3, tmp_result4); \ + const simde__m256i a = simde_mm256_or_si256(tmp_result, tmp_result3); + +// calculates psi_a = psi_r*a_r + psi_i*a_i +#define prodsum_psi_a_epi16_256(psi_r, a_r, psi_i, a_i, psi_a) \ + tmp_result = simde_mm256_mulhi_epi16(psi_r, a_r); \ + tmp_result = simde_mm256_slli_epi16(tmp_result, 1); \ + tmp_result2 = simde_mm256_mulhi_epi16(psi_i, a_i); \ + tmp_result2 = simde_mm256_slli_epi16(tmp_result2, 1); \ + simde__m256i psi_a = simde_mm256_adds_epi16(tmp_result, tmp_result2); + +// calculates a_sq = int_ch_mag*(a_r^2 + a_i^2)*scale_factor for 64-QAM +#define square_a_64qam_epi16_256(a_r, a_i, int_ch_mag, scale_factor, a_sq) \ + tmp_result = simde_mm256_mulhi_epi16(a_r, a_r); \ + tmp_result = simde_mm256_slli_epi16(tmp_result, 1); \ + tmp_result = simde_mm256_mulhi_epi16(tmp_result, scale_factor); \ + tmp_result = simde_mm256_slli_epi16(tmp_result, 3); \ + tmp_result = simde_mm256_mulhi_epi16(tmp_result, int_ch_mag); \ + tmp_result = simde_mm256_slli_epi16(tmp_result, 1); \ + tmp_result2 = simde_mm256_mulhi_epi16(a_i, a_i); \ + tmp_result2 = simde_mm256_slli_epi16(tmp_result2, 1); \ + tmp_result2 = simde_mm256_mulhi_epi16(tmp_result2, scale_factor); \ + tmp_result2 = simde_mm256_slli_epi16(tmp_result2, 3); \ + tmp_result2 = simde_mm256_mulhi_epi16(tmp_result2, int_ch_mag); \ + tmp_result2 = simde_mm256_slli_epi16(tmp_result2, 1); \ + const simde__m256i a_sq = simde_mm256_adds_epi16(tmp_result, tmp_result2); + +void separate_real_imag_parts(__m256i *out_re, __m256i *out_im, __m256i in0, __m256i in1) +{ + in0 = simde_mm256_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = simde_mm256_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = simde_mm256_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + in1 = simde_mm256_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = simde_mm256_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = simde_mm256_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // in0 = [Re(0,1,2,3) Im(0,1,2,3) Re(4,5,6,7) Im(4,5,6,7)] + // in0 = [Re(8,9,10,11) Im(8,9,10,11) Re(12,13,14,15) Im(12,13,14,15)] + + __m256i tmp0 = simde_mm256_unpacklo_epi64(in0, in1); + // axmm2 = [Re(0,1,2,3) Re(8,9,10,11) Re(4,5,6,7) Re(12,13,14,15)] + tmp0 = simde_mm256_permute4x64_epi64(tmp0, 0xd8); // Re(rho) + + __m256i tmp1 = simde_mm256_unpackhi_epi64(in0, in1); + // axmm3 = [Im(0,1,2,3) Im(8,9,10,11) Im(4,5,6,7) Im(12,13,14,15)] + tmp1 = simde_mm256_permute4x64_epi64(tmp1, 0xd8); // Im(rho) + + *out_re = tmp0; + *out_im = tmp1; +} + +/* + * This function computes the LLRs of stream 0 (s_0) in presence of the interfering stream 1 (s_1) assuming that both symbols are + * 64QAM. It can be used for both MU-MIMO interference-aware receiver or for SU-MIMO receivers. + * + * Input: + * stream0_in: MF filter output for 1st stream, i.e., y0' = h0'*y0 + * stream1_in: MF filter output for 2nd stream, i.e., y1' = h1'*y0 + * ch_mag: 4*h0/sqrt(42), [Re0 Im0 Re1 Im1] s.t. Im0=Re0, Im1=Re1, etc + * ch_mag_i: 4*h0/sqrt(42), [Re0 Im0 Re1 Im1] s.t. Im0=Re0, Im1=Re1, etc + * rho01: Channel cross correlation, i.e., rho01 = h0'*h1 + * length: Number of resource elements + * + * Output: + * stream0_out: Output LLRs for 1st stream + */ +void nr_ulsch_qam64_qam64(c16_t *stream0_in, + c16_t *stream1_in, + c16_t *ch_mag, + c16_t *ch_mag_i, + c16_t *stream0_out, + c16_t *rho01, + uint32_t length) +{ + __m256i *rho01_256i = (__m256i *)rho01; + __m256i *stream0_256i_in = (__m256i *)stream0_in; + __m256i *stream1_256i_in = (__m256i *)stream1_in; + __m256i *ch_mag_256i = (__m256i *)ch_mag; + __m256i *ch_mag_256i_i = (__m256i *)ch_mag_i; + + __m256i ONE_OVER_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(10112)); // round(1/sqrt(42)*2^16) + __m256i THREE_OVER_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(30337)); // round(3/sqrt(42)*2^16) + __m256i FIVE_OVER_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(25281)); // round(5/sqrt(42)*2^15) + __m256i SEVEN_OVER_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(17697)); // round(7/sqrt(42)*2^14) Q2.14 + __m256i ONE_OVER_SQRT_2 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(23170)); // round(1/sqrt(2)*2^15) + __m256i ONE_OVER_SQRT_2_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(3575)); // round(1/sqrt(2*42)*2^15) + __m256i THREE_OVER_SQRT_2_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(10726)); // round(3/sqrt(2*42)*2^15) + __m256i FIVE_OVER_SQRT_2_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(17876)); // round(5/sqrt(2*42)*2^15) + __m256i SEVEN_OVER_SQRT_2_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(25027)); // round(7/sqrt(2*42)*2^15) + __m256i FORTYNINE_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(30969)); // round(49/(4*sqrt(42))*2^14), Q2.14 + __m256i THIRTYSEVEN_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(23385)); // round(37/(4*sqrt(42))*2^14), Q2.14 + __m256i TWENTYFIVE_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(31601)); // round(25/(4*sqrt(42))*2^15) + __m256i TWENTYNINE_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(18329)); // round(29/(4*sqrt(42))*2^15), Q2.14 + __m256i SEVENTEEN_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(21489)); // round(17/(4*sqrt(42))*2^15) + __m256i NINE_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(11376)); // round(9/(4*sqrt(42))*2^15) + __m256i THIRTEEN_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(16433)); // round(13/(4*sqrt(42))*2^15) + __m256i FIVE_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(6320)); // round(5/(4*sqrt(42))*2^15) + __m256i ONE_OVER_FOUR_SQRT_42 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(1264)); // round(1/(4*sqrt(42))*2^15) + __m256i SQRT_42_OVER_FOUR = simde_mm256_broadcastw_epi16(_mm_set1_epi16(13272)); // round(sqrt(42)/4*2^13), Q3.12 + + __m256i ch_mag_des; + __m256i ch_mag_int; + __m256i ch_mag_98_over_42_with_sigma2; + __m256i ch_mag_74_over_42_with_sigma2; + __m256i ch_mag_58_over_42_with_sigma2; + __m256i ch_mag_50_over_42_with_sigma2; + __m256i ch_mag_34_over_42_with_sigma2; + __m256i ch_mag_18_over_42_with_sigma2; + __m256i ch_mag_26_over_42_with_sigma2; + __m256i ch_mag_10_over_42_with_sigma2; + __m256i ch_mag_2_over_42_with_sigma2; + __m256i y0r_one_over_sqrt_21; + __m256i y0r_three_over_sqrt_21; + __m256i y0r_five_over_sqrt_21; + __m256i y0r_seven_over_sqrt_21; + __m256i y0i_one_over_sqrt_21; + __m256i y0i_three_over_sqrt_21; + __m256i y0i_five_over_sqrt_21; + __m256i y0i_seven_over_sqrt_21; + __m256i ch_mag_int_with_sigma2; + __m256i two_ch_mag_int_with_sigma2; + __m256i three_ch_mag_int_with_sigma2; + + uint32_t len256 = length >> 3; + + for (int i = 0; i < len256; i += 2) { + + // Get rho + simde__m256i xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; + separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); + + simde__m256i rho_rpi = simde_mm256_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) + simde__m256i rho_rmi = simde_mm256_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) + + // Compute the different rhos + simde__m256i rho_rpi_1_1 = simde_mm256_mulhi_epi16(rho_rpi, ONE_OVER_SQRT_42); + simde__m256i rho_rmi_1_1 = simde_mm256_mulhi_epi16(rho_rmi, ONE_OVER_SQRT_42); + simde__m256i rho_rpi_3_3 = simde_mm256_mulhi_epi16(rho_rpi, THREE_OVER_SQRT_42); + simde__m256i rho_rmi_3_3 = simde_mm256_mulhi_epi16(rho_rmi, THREE_OVER_SQRT_42); + simde__m256i rho_rpi_5_5 = simde_mm256_mulhi_epi16(rho_rpi, FIVE_OVER_SQRT_42); + simde__m256i rho_rmi_5_5 = simde_mm256_mulhi_epi16(rho_rmi, FIVE_OVER_SQRT_42); + simde__m256i rho_rpi_7_7 = simde_mm256_mulhi_epi16(rho_rpi, SEVEN_OVER_SQRT_42); + simde__m256i rho_rmi_7_7 = simde_mm256_mulhi_epi16(rho_rmi, SEVEN_OVER_SQRT_42); + + rho_rpi_5_5 = simde_mm256_slli_epi16(rho_rpi_5_5, 1); + rho_rmi_5_5 = simde_mm256_slli_epi16(rho_rmi_5_5, 1); + rho_rpi_7_7 = simde_mm256_slli_epi16(rho_rpi_7_7, 2); + rho_rmi_7_7 = simde_mm256_slli_epi16(rho_rmi_7_7, 2); + + xmm4 = simde_mm256_mulhi_epi16(xmm2, ONE_OVER_SQRT_42); + xmm5 = simde_mm256_mulhi_epi16(xmm3, ONE_OVER_SQRT_42); + xmm6 = simde_mm256_mulhi_epi16(xmm3, THREE_OVER_SQRT_42); + xmm7 = simde_mm256_mulhi_epi16(xmm3, FIVE_OVER_SQRT_42); + xmm8 = simde_mm256_mulhi_epi16(xmm3, SEVEN_OVER_SQRT_42); + xmm7 = simde_mm256_slli_epi16(xmm7, 1); + xmm8 = simde_mm256_slli_epi16(xmm8, 2); + + simde__m256i rho_rpi_1_3 = simde_mm256_adds_epi16(xmm4, xmm6); + simde__m256i rho_rmi_1_3 = simde_mm256_subs_epi16(xmm4, xmm6); + simde__m256i rho_rpi_1_5 = simde_mm256_adds_epi16(xmm4, xmm7); + simde__m256i rho_rmi_1_5 = simde_mm256_subs_epi16(xmm4, xmm7); + simde__m256i rho_rpi_1_7 = simde_mm256_adds_epi16(xmm4, xmm8); + simde__m256i rho_rmi_1_7 = simde_mm256_subs_epi16(xmm4, xmm8); + + xmm4 = simde_mm256_mulhi_epi16(xmm2, THREE_OVER_SQRT_42); + simde__m256i rho_rpi_3_1 = simde_mm256_adds_epi16(xmm4, xmm5); + simde__m256i rho_rmi_3_1 = simde_mm256_subs_epi16(xmm4, xmm5); + simde__m256i rho_rpi_3_5 = simde_mm256_adds_epi16(xmm4, xmm7); + simde__m256i rho_rmi_3_5 = simde_mm256_subs_epi16(xmm4, xmm7); + simde__m256i rho_rpi_3_7 = simde_mm256_adds_epi16(xmm4, xmm8); + simde__m256i rho_rmi_3_7 = simde_mm256_subs_epi16(xmm4, xmm8); + + xmm4 = simde_mm256_mulhi_epi16(xmm2, FIVE_OVER_SQRT_42); + xmm4 = simde_mm256_slli_epi16(xmm4, 1); + simde__m256i rho_rpi_5_1 = simde_mm256_adds_epi16(xmm4, xmm5); + simde__m256i rho_rmi_5_1 = simde_mm256_subs_epi16(xmm4, xmm5); + simde__m256i rho_rpi_5_3 = simde_mm256_adds_epi16(xmm4, xmm6); + simde__m256i rho_rmi_5_3 = simde_mm256_subs_epi16(xmm4, xmm6); + simde__m256i rho_rpi_5_7 = simde_mm256_adds_epi16(xmm4, xmm8); + simde__m256i rho_rmi_5_7 = simde_mm256_subs_epi16(xmm4, xmm8); + + xmm4 = simde_mm256_mulhi_epi16(xmm2, SEVEN_OVER_SQRT_42); + xmm4 = simde_mm256_slli_epi16(xmm4, 2); + simde__m256i rho_rpi_7_1 = simde_mm256_adds_epi16(xmm4, xmm5); + simde__m256i rho_rmi_7_1 = simde_mm256_subs_epi16(xmm4, xmm5); + simde__m256i rho_rpi_7_3 = simde_mm256_adds_epi16(xmm4, xmm6); + simde__m256i rho_rmi_7_3 = simde_mm256_subs_epi16(xmm4, xmm6); + simde__m256i rho_rpi_7_5 = simde_mm256_adds_epi16(xmm4, xmm7); + simde__m256i rho_rmi_7_5 = simde_mm256_subs_epi16(xmm4, xmm7); + + // Rearrange interfering MF output + simde__m256i y1r, y1i, xmm0; + separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); + + // Psi_r calculation from rho_rpi or rho_rmi + xmm0 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(0)); // ZERO for abs_pi16 + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_7, y1r); + + simde__m256i psi_r_p7_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_5, y1r); + simde__m256i psi_r_p7_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_3, y1r); + simde__m256i psi_r_p7_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_1, y1r); + simde__m256i psi_r_p7_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_1, y1r); + simde__m256i psi_r_p7_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_3, y1r); + simde__m256i psi_r_p7_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_5, y1r); + simde__m256i psi_r_p7_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_7, y1r); + simde__m256i psi_r_p7_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_7, y1r); + simde__m256i psi_r_p5_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_5, y1r); + simde__m256i psi_r_p5_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_3, y1r); + simde__m256i psi_r_p5_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_1, y1r); + simde__m256i psi_r_p5_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_1, y1r); + simde__m256i psi_r_p5_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_3, y1r); + simde__m256i psi_r_p5_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_5, y1r); + simde__m256i psi_r_p5_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_7, y1r); + simde__m256i psi_r_p5_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_7, y1r); + simde__m256i psi_r_p3_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_5, y1r); + simde__m256i psi_r_p3_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_3, y1r); + simde__m256i psi_r_p3_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_1, y1r); + simde__m256i psi_r_p3_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_1, y1r); + simde__m256i psi_r_p3_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_3, y1r); + simde__m256i psi_r_p3_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_5, y1r); + simde__m256i psi_r_p3_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_7, y1r); + simde__m256i psi_r_p3_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_7, y1r); + simde__m256i psi_r_p1_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_5, y1r); + simde__m256i psi_r_p1_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_3, y1r); + simde__m256i psi_r_p1_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_1, y1r); + simde__m256i psi_r_p1_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_1, y1r); + simde__m256i psi_r_p1_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_3, y1r); + simde__m256i psi_r_p1_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_5, y1r); + simde__m256i psi_r_p1_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_7, y1r); + simde__m256i psi_r_p1_m7 = simde_mm256_abs_epi16(xmm2); + + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_7, y1r); + simde__m256i psi_r_m1_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_5, y1r); + simde__m256i psi_r_m1_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_3, y1r); + simde__m256i psi_r_m1_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_1, y1r); + simde__m256i psi_r_m1_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_1, y1r); + simde__m256i psi_r_m1_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_3, y1r); + simde__m256i psi_r_m1_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_5, y1r); + simde__m256i psi_r_m1_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_7, y1r); + simde__m256i psi_r_m1_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_7, y1r); + simde__m256i psi_r_m3_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_5, y1r); + simde__m256i psi_r_m3_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_3, y1r); + simde__m256i psi_r_m3_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_1, y1r); + simde__m256i psi_r_m3_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_1, y1r); + simde__m256i psi_r_m3_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_3, y1r); + simde__m256i psi_r_m3_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_5, y1r); + simde__m256i psi_r_m3_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_7, y1r); + simde__m256i psi_r_m3_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_7, y1r); + simde__m256i psi_r_m5_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_5, y1r); + simde__m256i psi_r_m5_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_3, y1r); + simde__m256i psi_r_m5_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_1, y1r); + simde__m256i psi_r_m5_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_1, y1r); + simde__m256i psi_r_m5_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_3, y1r); + simde__m256i psi_r_m5_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_5, y1r); + simde__m256i psi_r_m5_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_7, y1r); + simde__m256i psi_r_m5_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_7, y1r); + simde__m256i psi_r_m7_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_5, y1r); + simde__m256i psi_r_m7_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_3, y1r); + simde__m256i psi_r_m7_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_1, y1r); + simde__m256i psi_r_m7_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_1, y1r); + simde__m256i psi_r_m7_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_3, y1r); + simde__m256i psi_r_m7_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_5, y1r); + simde__m256i psi_r_m7_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_7, y1r); + simde__m256i psi_r_m7_m7 = simde_mm256_abs_epi16(xmm2); + + // Simde__M256i Psi_i calculation from rho_rpi or rho_rmi + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_7, y1i); + simde__m256i psi_i_p7_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_7, y1i); + simde__m256i psi_i_p7_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_7, y1i); + simde__m256i psi_i_p7_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_7, y1i); + simde__m256i psi_i_p7_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_7, y1i); + simde__m256i psi_i_p7_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_7, y1i); + simde__m256i psi_i_p7_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_7, y1i); + simde__m256i psi_i_p7_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_7, y1i); + simde__m256i psi_i_p7_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_5, y1i); + simde__m256i psi_i_p5_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_5, y1i); + simde__m256i psi_i_p5_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_5, y1i); + simde__m256i psi_i_p5_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_5, y1i); + simde__m256i psi_i_p5_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_5, y1i); + simde__m256i psi_i_p5_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_5, y1i); + simde__m256i psi_i_p5_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_5, y1i); + simde__m256i psi_i_p5_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_5, y1i); + simde__m256i psi_i_p5_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_3, y1i); + simde__m256i psi_i_p3_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_3, y1i); + simde__m256i psi_i_p3_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_3, y1i); + simde__m256i psi_i_p3_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_3, y1i); + simde__m256i psi_i_p3_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_3, y1i); + simde__m256i psi_i_p3_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_3, y1i); + simde__m256i psi_i_p3_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_3, y1i); + simde__m256i psi_i_p3_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_3, y1i); + simde__m256i psi_i_p3_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_7_1, y1i); + simde__m256i psi_i_p1_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_5_1, y1i); + simde__m256i psi_i_p1_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_3_1, y1i); + simde__m256i psi_i_p1_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rmi_1_1, y1i); + simde__m256i psi_i_p1_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_1_1, y1i); + simde__m256i psi_i_p1_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_3_1, y1i); + simde__m256i psi_i_p1_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_5_1, y1i); + simde__m256i psi_i_p1_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rpi_7_1, y1i); + simde__m256i psi_i_p1_m7 = simde_mm256_abs_epi16(xmm2); + + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_1, y1i); + simde__m256i psi_i_m1_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_1, y1i); + simde__m256i psi_i_m1_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_1, y1i); + simde__m256i psi_i_m1_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_1, y1i); + simde__m256i psi_i_m1_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_1, y1i); + simde__m256i psi_i_m1_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_1, y1i); + simde__m256i psi_i_m1_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_1, y1i); + simde__m256i psi_i_m1_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_1, y1i); + simde__m256i psi_i_m1_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_3, y1i); + simde__m256i psi_i_m3_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_3, y1i); + simde__m256i psi_i_m3_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_3, y1i); + simde__m256i psi_i_m3_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_3, y1i); + simde__m256i psi_i_m3_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_3, y1i); + simde__m256i psi_i_m3_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_3, y1i); + simde__m256i psi_i_m3_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_3, y1i); + simde__m256i psi_i_m3_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_3, y1i); + simde__m256i psi_i_m3_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_5, y1i); + simde__m256i psi_i_m5_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_5, y1i); + simde__m256i psi_i_m5_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_5, y1i); + simde__m256i psi_i_m5_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_5, y1i); + simde__m256i psi_i_m5_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_5, y1i); + simde__m256i psi_i_m5_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_5, y1i); + simde__m256i psi_i_m5_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_5, y1i); + simde__m256i psi_i_m5_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_5, y1i); + simde__m256i psi_i_m5_m7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_7_7, y1i); + simde__m256i psi_i_m7_p7 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_5_7, y1i); + simde__m256i psi_i_m7_p5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_3_7, y1i); + simde__m256i psi_i_m7_p3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_subs_epi16(rho_rpi_1_7, y1i); + simde__m256i psi_i_m7_p1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_1_7, y1i); + simde__m256i psi_i_m7_m1 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_3_7, y1i); + simde__m256i psi_i_m7_m3 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_5_7, y1i); + simde__m256i psi_i_m7_m5 = simde_mm256_abs_epi16(xmm2); + xmm2 = simde_mm256_adds_epi16(rho_rmi_7_7, y1i); + simde__m256i psi_i_m7_m7 = simde_mm256_abs_epi16(xmm2); + + // Rearrange desired MF output + simde__m256i y0r, y0i; + separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); + + // Rearrange desired channel magnitudes + // [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2),...,,|h|^2(7),|h|^2(7)]*(2/sqrt(10)) + // xmm2 is dummy variable that contains the same values as ch_mag_des + separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); + + // Rearrange interfering channel magnitudes + separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); + + y0r_one_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_SQRT_42); + y0r_three_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, THREE_OVER_SQRT_42); + y0r_five_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, FIVE_OVER_SQRT_42); + y0r_five_over_sqrt_21 = simde_mm256_slli_epi16(y0r_five_over_sqrt_21, 1); + y0r_seven_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, SEVEN_OVER_SQRT_42); + y0r_seven_over_sqrt_21 = simde_mm256_slli_epi16(y0r_seven_over_sqrt_21, 2); // Q2.14 + + y0i_one_over_sqrt_21 = simde_mm256_mulhi_epi16(y0i, ONE_OVER_SQRT_42); + y0i_three_over_sqrt_21 = simde_mm256_mulhi_epi16(y0i, THREE_OVER_SQRT_42); + y0i_five_over_sqrt_21 = simde_mm256_mulhi_epi16(y0i, FIVE_OVER_SQRT_42); + y0i_five_over_sqrt_21 = simde_mm256_slli_epi16(y0i_five_over_sqrt_21, 1); + y0i_seven_over_sqrt_21 = simde_mm256_mulhi_epi16(y0i, SEVEN_OVER_SQRT_42); + y0i_seven_over_sqrt_21 = simde_mm256_slli_epi16(y0i_seven_over_sqrt_21, 2); // Q2.14 + + simde__m256i y0_p_7_1 = simde_mm256_adds_epi16(y0r_seven_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_p_7_3 = simde_mm256_adds_epi16(y0r_seven_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_p_7_5 = simde_mm256_adds_epi16(y0r_seven_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_p_7_7 = simde_mm256_adds_epi16(y0r_seven_over_sqrt_21, y0i_seven_over_sqrt_21); + simde__m256i y0_p_5_1 = simde_mm256_adds_epi16(y0r_five_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_p_5_3 = simde_mm256_adds_epi16(y0r_five_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_p_5_5 = simde_mm256_adds_epi16(y0r_five_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_p_5_7 = simde_mm256_adds_epi16(y0r_five_over_sqrt_21, y0i_seven_over_sqrt_21); + simde__m256i y0_p_3_1 = simde_mm256_adds_epi16(y0r_three_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_p_3_3 = simde_mm256_adds_epi16(y0r_three_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_p_3_5 = simde_mm256_adds_epi16(y0r_three_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_p_3_7 = simde_mm256_adds_epi16(y0r_three_over_sqrt_21, y0i_seven_over_sqrt_21); + simde__m256i y0_p_1_1 = simde_mm256_adds_epi16(y0r_one_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_p_1_3 = simde_mm256_adds_epi16(y0r_one_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_p_1_5 = simde_mm256_adds_epi16(y0r_one_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_p_1_7 = simde_mm256_adds_epi16(y0r_one_over_sqrt_21, y0i_seven_over_sqrt_21); + + simde__m256i y0_m_1_1 = simde_mm256_subs_epi16(y0r_one_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_m_1_3 = simde_mm256_subs_epi16(y0r_one_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_m_1_5 = simde_mm256_subs_epi16(y0r_one_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_m_1_7 = simde_mm256_subs_epi16(y0r_one_over_sqrt_21, y0i_seven_over_sqrt_21); + simde__m256i y0_m_3_1 = simde_mm256_subs_epi16(y0r_three_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_m_3_3 = simde_mm256_subs_epi16(y0r_three_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_m_3_5 = simde_mm256_subs_epi16(y0r_three_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_m_3_7 = simde_mm256_subs_epi16(y0r_three_over_sqrt_21, y0i_seven_over_sqrt_21); + simde__m256i y0_m_5_1 = simde_mm256_subs_epi16(y0r_five_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_m_5_3 = simde_mm256_subs_epi16(y0r_five_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_m_5_5 = simde_mm256_subs_epi16(y0r_five_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_m_5_7 = simde_mm256_subs_epi16(y0r_five_over_sqrt_21, y0i_seven_over_sqrt_21); + simde__m256i y0_m_7_1 = simde_mm256_subs_epi16(y0r_seven_over_sqrt_21, y0i_one_over_sqrt_21); + simde__m256i y0_m_7_3 = simde_mm256_subs_epi16(y0r_seven_over_sqrt_21, y0i_three_over_sqrt_21); + simde__m256i y0_m_7_5 = simde_mm256_subs_epi16(y0r_seven_over_sqrt_21, y0i_five_over_sqrt_21); + simde__m256i y0_m_7_7 = simde_mm256_subs_epi16(y0r_seven_over_sqrt_21, y0i_seven_over_sqrt_21); + + // Detection of interference term + ch_mag_int_with_sigma2 = simde_mm256_srai_epi16(ch_mag_int, 1); // *2 + two_ch_mag_int_with_sigma2 = ch_mag_int; // *4 + three_ch_mag_int_with_sigma2 = simde_mm256_adds_epi16(ch_mag_int_with_sigma2, two_ch_mag_int_with_sigma2); // *6 + simde__m256i tmp_result, tmp_result2, tmp_result3, tmp_result4; + interference_abs_64qam_epi16_256(psi_r_p7_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p7_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p7_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p5_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p5_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p3_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p3_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_p1_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_p1_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m1_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m1_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m3_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m3_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m5_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m5_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_r_m7_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_r_m7_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + + interference_abs_64qam_epi16_256(psi_i_p7_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p7_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p7_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p5_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p5_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p3_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p3_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_p1_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_p1_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m1_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m1_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m3_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m3_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m5_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m5_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_p7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_p7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_p5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_p5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_p3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_p3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_p1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_p1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_m1, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_m1, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_m3, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_m3, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_m5, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_m5, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + interference_abs_64qam_epi16_256(psi_i_m7_m7, + ch_mag_int_with_sigma2, + two_ch_mag_int_with_sigma2, + three_ch_mag_int_with_sigma2, + a_i_m7_m7, + ONE_OVER_SQRT_2_42, + THREE_OVER_SQRT_2_42, + FIVE_OVER_SQRT_2_42, + SEVEN_OVER_SQRT_2_42); + + // Calculation of a group of two terms in the bit metric involving product of psi and interference + prodsum_psi_a_epi16_256(psi_r_p7_p7, a_r_p7_p7, psi_i_p7_p7, a_i_p7_p7, psi_a_p7_p7); + prodsum_psi_a_epi16_256(psi_r_p7_p5, a_r_p7_p5, psi_i_p7_p5, a_i_p7_p5, psi_a_p7_p5); + prodsum_psi_a_epi16_256(psi_r_p7_p3, a_r_p7_p3, psi_i_p7_p3, a_i_p7_p3, psi_a_p7_p3); + prodsum_psi_a_epi16_256(psi_r_p7_p1, a_r_p7_p1, psi_i_p7_p1, a_i_p7_p1, psi_a_p7_p1); + prodsum_psi_a_epi16_256(psi_r_p7_m1, a_r_p7_m1, psi_i_p7_m1, a_i_p7_m1, psi_a_p7_m1); + prodsum_psi_a_epi16_256(psi_r_p7_m3, a_r_p7_m3, psi_i_p7_m3, a_i_p7_m3, psi_a_p7_m3); + prodsum_psi_a_epi16_256(psi_r_p7_m5, a_r_p7_m5, psi_i_p7_m5, a_i_p7_m5, psi_a_p7_m5); + prodsum_psi_a_epi16_256(psi_r_p7_m7, a_r_p7_m7, psi_i_p7_m7, a_i_p7_m7, psi_a_p7_m7); + prodsum_psi_a_epi16_256(psi_r_p5_p7, a_r_p5_p7, psi_i_p5_p7, a_i_p5_p7, psi_a_p5_p7); + prodsum_psi_a_epi16_256(psi_r_p5_p5, a_r_p5_p5, psi_i_p5_p5, a_i_p5_p5, psi_a_p5_p5); + prodsum_psi_a_epi16_256(psi_r_p5_p3, a_r_p5_p3, psi_i_p5_p3, a_i_p5_p3, psi_a_p5_p3); + prodsum_psi_a_epi16_256(psi_r_p5_p1, a_r_p5_p1, psi_i_p5_p1, a_i_p5_p1, psi_a_p5_p1); + prodsum_psi_a_epi16_256(psi_r_p5_m1, a_r_p5_m1, psi_i_p5_m1, a_i_p5_m1, psi_a_p5_m1); + prodsum_psi_a_epi16_256(psi_r_p5_m3, a_r_p5_m3, psi_i_p5_m3, a_i_p5_m3, psi_a_p5_m3); + prodsum_psi_a_epi16_256(psi_r_p5_m5, a_r_p5_m5, psi_i_p5_m5, a_i_p5_m5, psi_a_p5_m5); + prodsum_psi_a_epi16_256(psi_r_p5_m7, a_r_p5_m7, psi_i_p5_m7, a_i_p5_m7, psi_a_p5_m7); + prodsum_psi_a_epi16_256(psi_r_p3_p7, a_r_p3_p7, psi_i_p3_p7, a_i_p3_p7, psi_a_p3_p7); + prodsum_psi_a_epi16_256(psi_r_p3_p5, a_r_p3_p5, psi_i_p3_p5, a_i_p3_p5, psi_a_p3_p5); + prodsum_psi_a_epi16_256(psi_r_p3_p3, a_r_p3_p3, psi_i_p3_p3, a_i_p3_p3, psi_a_p3_p3); + prodsum_psi_a_epi16_256(psi_r_p3_p1, a_r_p3_p1, psi_i_p3_p1, a_i_p3_p1, psi_a_p3_p1); + prodsum_psi_a_epi16_256(psi_r_p3_m1, a_r_p3_m1, psi_i_p3_m1, a_i_p3_m1, psi_a_p3_m1); + prodsum_psi_a_epi16_256(psi_r_p3_m3, a_r_p3_m3, psi_i_p3_m3, a_i_p3_m3, psi_a_p3_m3); + prodsum_psi_a_epi16_256(psi_r_p3_m5, a_r_p3_m5, psi_i_p3_m5, a_i_p3_m5, psi_a_p3_m5); + prodsum_psi_a_epi16_256(psi_r_p3_m7, a_r_p3_m7, psi_i_p3_m7, a_i_p3_m7, psi_a_p3_m7); + prodsum_psi_a_epi16_256(psi_r_p1_p7, a_r_p1_p7, psi_i_p1_p7, a_i_p1_p7, psi_a_p1_p7); + prodsum_psi_a_epi16_256(psi_r_p1_p5, a_r_p1_p5, psi_i_p1_p5, a_i_p1_p5, psi_a_p1_p5); + prodsum_psi_a_epi16_256(psi_r_p1_p3, a_r_p1_p3, psi_i_p1_p3, a_i_p1_p3, psi_a_p1_p3); + prodsum_psi_a_epi16_256(psi_r_p1_p1, a_r_p1_p1, psi_i_p1_p1, a_i_p1_p1, psi_a_p1_p1); + prodsum_psi_a_epi16_256(psi_r_p1_m1, a_r_p1_m1, psi_i_p1_m1, a_i_p1_m1, psi_a_p1_m1); + prodsum_psi_a_epi16_256(psi_r_p1_m3, a_r_p1_m3, psi_i_p1_m3, a_i_p1_m3, psi_a_p1_m3); + prodsum_psi_a_epi16_256(psi_r_p1_m5, a_r_p1_m5, psi_i_p1_m5, a_i_p1_m5, psi_a_p1_m5); + prodsum_psi_a_epi16_256(psi_r_p1_m7, a_r_p1_m7, psi_i_p1_m7, a_i_p1_m7, psi_a_p1_m7); + prodsum_psi_a_epi16_256(psi_r_m1_p7, a_r_m1_p7, psi_i_m1_p7, a_i_m1_p7, psi_a_m1_p7); + prodsum_psi_a_epi16_256(psi_r_m1_p5, a_r_m1_p5, psi_i_m1_p5, a_i_m1_p5, psi_a_m1_p5); + prodsum_psi_a_epi16_256(psi_r_m1_p3, a_r_m1_p3, psi_i_m1_p3, a_i_m1_p3, psi_a_m1_p3); + prodsum_psi_a_epi16_256(psi_r_m1_p1, a_r_m1_p1, psi_i_m1_p1, a_i_m1_p1, psi_a_m1_p1); + prodsum_psi_a_epi16_256(psi_r_m1_m1, a_r_m1_m1, psi_i_m1_m1, a_i_m1_m1, psi_a_m1_m1); + prodsum_psi_a_epi16_256(psi_r_m1_m3, a_r_m1_m3, psi_i_m1_m3, a_i_m1_m3, psi_a_m1_m3); + prodsum_psi_a_epi16_256(psi_r_m1_m5, a_r_m1_m5, psi_i_m1_m5, a_i_m1_m5, psi_a_m1_m5); + prodsum_psi_a_epi16_256(psi_r_m1_m7, a_r_m1_m7, psi_i_m1_m7, a_i_m1_m7, psi_a_m1_m7); + prodsum_psi_a_epi16_256(psi_r_m3_p7, a_r_m3_p7, psi_i_m3_p7, a_i_m3_p7, psi_a_m3_p7); + prodsum_psi_a_epi16_256(psi_r_m3_p5, a_r_m3_p5, psi_i_m3_p5, a_i_m3_p5, psi_a_m3_p5); + prodsum_psi_a_epi16_256(psi_r_m3_p3, a_r_m3_p3, psi_i_m3_p3, a_i_m3_p3, psi_a_m3_p3); + prodsum_psi_a_epi16_256(psi_r_m3_p1, a_r_m3_p1, psi_i_m3_p1, a_i_m3_p1, psi_a_m3_p1); + prodsum_psi_a_epi16_256(psi_r_m3_m1, a_r_m3_m1, psi_i_m3_m1, a_i_m3_m1, psi_a_m3_m1); + prodsum_psi_a_epi16_256(psi_r_m3_m3, a_r_m3_m3, psi_i_m3_m3, a_i_m3_m3, psi_a_m3_m3); + prodsum_psi_a_epi16_256(psi_r_m3_m5, a_r_m3_m5, psi_i_m3_m5, a_i_m3_m5, psi_a_m3_m5); + prodsum_psi_a_epi16_256(psi_r_m3_m7, a_r_m3_m7, psi_i_m3_m7, a_i_m3_m7, psi_a_m3_m7); + prodsum_psi_a_epi16_256(psi_r_m5_p7, a_r_m5_p7, psi_i_m5_p7, a_i_m5_p7, psi_a_m5_p7); + prodsum_psi_a_epi16_256(psi_r_m5_p5, a_r_m5_p5, psi_i_m5_p5, a_i_m5_p5, psi_a_m5_p5); + prodsum_psi_a_epi16_256(psi_r_m5_p3, a_r_m5_p3, psi_i_m5_p3, a_i_m5_p3, psi_a_m5_p3); + prodsum_psi_a_epi16_256(psi_r_m5_p1, a_r_m5_p1, psi_i_m5_p1, a_i_m5_p1, psi_a_m5_p1); + prodsum_psi_a_epi16_256(psi_r_m5_m1, a_r_m5_m1, psi_i_m5_m1, a_i_m5_m1, psi_a_m5_m1); + prodsum_psi_a_epi16_256(psi_r_m5_m3, a_r_m5_m3, psi_i_m5_m3, a_i_m5_m3, psi_a_m5_m3); + prodsum_psi_a_epi16_256(psi_r_m5_m5, a_r_m5_m5, psi_i_m5_m5, a_i_m5_m5, psi_a_m5_m5); + prodsum_psi_a_epi16_256(psi_r_m5_m7, a_r_m5_m7, psi_i_m5_m7, a_i_m5_m7, psi_a_m5_m7); + prodsum_psi_a_epi16_256(psi_r_m7_p7, a_r_m7_p7, psi_i_m7_p7, a_i_m7_p7, psi_a_m7_p7); + prodsum_psi_a_epi16_256(psi_r_m7_p5, a_r_m7_p5, psi_i_m7_p5, a_i_m7_p5, psi_a_m7_p5); + prodsum_psi_a_epi16_256(psi_r_m7_p3, a_r_m7_p3, psi_i_m7_p3, a_i_m7_p3, psi_a_m7_p3); + prodsum_psi_a_epi16_256(psi_r_m7_p1, a_r_m7_p1, psi_i_m7_p1, a_i_m7_p1, psi_a_m7_p1); + prodsum_psi_a_epi16_256(psi_r_m7_m1, a_r_m7_m1, psi_i_m7_m1, a_i_m7_m1, psi_a_m7_m1); + prodsum_psi_a_epi16_256(psi_r_m7_m3, a_r_m7_m3, psi_i_m7_m3, a_i_m7_m3, psi_a_m7_m3); + prodsum_psi_a_epi16_256(psi_r_m7_m5, a_r_m7_m5, psi_i_m7_m5, a_i_m7_m5, psi_a_m7_m5); + prodsum_psi_a_epi16_256(psi_r_m7_m7, a_r_m7_m7, psi_i_m7_m7, a_i_m7_m7, psi_a_m7_m7); + + // Multiply by sqrt(2) + psi_a_p7_p7 = simde_mm256_mulhi_epi16(psi_a_p7_p7, ONE_OVER_SQRT_2); + psi_a_p7_p7 = simde_mm256_slli_epi16(psi_a_p7_p7, 2); + psi_a_p7_p5 = simde_mm256_mulhi_epi16(psi_a_p7_p5, ONE_OVER_SQRT_2); + psi_a_p7_p5 = simde_mm256_slli_epi16(psi_a_p7_p5, 2); + psi_a_p7_p3 = simde_mm256_mulhi_epi16(psi_a_p7_p3, ONE_OVER_SQRT_2); + psi_a_p7_p3 = simde_mm256_slli_epi16(psi_a_p7_p3, 2); + psi_a_p7_p1 = simde_mm256_mulhi_epi16(psi_a_p7_p1, ONE_OVER_SQRT_2); + psi_a_p7_p1 = simde_mm256_slli_epi16(psi_a_p7_p1, 2); + psi_a_p7_m1 = simde_mm256_mulhi_epi16(psi_a_p7_m1, ONE_OVER_SQRT_2); + psi_a_p7_m1 = simde_mm256_slli_epi16(psi_a_p7_m1, 2); + psi_a_p7_m3 = simde_mm256_mulhi_epi16(psi_a_p7_m3, ONE_OVER_SQRT_2); + psi_a_p7_m3 = simde_mm256_slli_epi16(psi_a_p7_m3, 2); + psi_a_p7_m5 = simde_mm256_mulhi_epi16(psi_a_p7_m5, ONE_OVER_SQRT_2); + psi_a_p7_m5 = simde_mm256_slli_epi16(psi_a_p7_m5, 2); + psi_a_p7_m7 = simde_mm256_mulhi_epi16(psi_a_p7_m7, ONE_OVER_SQRT_2); + psi_a_p7_m7 = simde_mm256_slli_epi16(psi_a_p7_m7, 2); + psi_a_p5_p7 = simde_mm256_mulhi_epi16(psi_a_p5_p7, ONE_OVER_SQRT_2); + psi_a_p5_p7 = simde_mm256_slli_epi16(psi_a_p5_p7, 2); + psi_a_p5_p5 = simde_mm256_mulhi_epi16(psi_a_p5_p5, ONE_OVER_SQRT_2); + psi_a_p5_p5 = simde_mm256_slli_epi16(psi_a_p5_p5, 2); + psi_a_p5_p3 = simde_mm256_mulhi_epi16(psi_a_p5_p3, ONE_OVER_SQRT_2); + psi_a_p5_p3 = simde_mm256_slli_epi16(psi_a_p5_p3, 2); + psi_a_p5_p1 = simde_mm256_mulhi_epi16(psi_a_p5_p1, ONE_OVER_SQRT_2); + psi_a_p5_p1 = simde_mm256_slli_epi16(psi_a_p5_p1, 2); + psi_a_p5_m1 = simde_mm256_mulhi_epi16(psi_a_p5_m1, ONE_OVER_SQRT_2); + psi_a_p5_m1 = simde_mm256_slli_epi16(psi_a_p5_m1, 2); + psi_a_p5_m3 = simde_mm256_mulhi_epi16(psi_a_p5_m3, ONE_OVER_SQRT_2); + psi_a_p5_m3 = simde_mm256_slli_epi16(psi_a_p5_m3, 2); + psi_a_p5_m5 = simde_mm256_mulhi_epi16(psi_a_p5_m5, ONE_OVER_SQRT_2); + psi_a_p5_m5 = simde_mm256_slli_epi16(psi_a_p5_m5, 2); + psi_a_p5_m7 = simde_mm256_mulhi_epi16(psi_a_p5_m7, ONE_OVER_SQRT_2); + psi_a_p5_m7 = simde_mm256_slli_epi16(psi_a_p5_m7, 2); + psi_a_p3_p7 = simde_mm256_mulhi_epi16(psi_a_p3_p7, ONE_OVER_SQRT_2); + psi_a_p3_p7 = simde_mm256_slli_epi16(psi_a_p3_p7, 2); + psi_a_p3_p5 = simde_mm256_mulhi_epi16(psi_a_p3_p5, ONE_OVER_SQRT_2); + psi_a_p3_p5 = simde_mm256_slli_epi16(psi_a_p3_p5, 2); + psi_a_p3_p3 = simde_mm256_mulhi_epi16(psi_a_p3_p3, ONE_OVER_SQRT_2); + psi_a_p3_p3 = simde_mm256_slli_epi16(psi_a_p3_p3, 2); + psi_a_p3_p1 = simde_mm256_mulhi_epi16(psi_a_p3_p1, ONE_OVER_SQRT_2); + psi_a_p3_p1 = simde_mm256_slli_epi16(psi_a_p3_p1, 2); + psi_a_p3_m1 = simde_mm256_mulhi_epi16(psi_a_p3_m1, ONE_OVER_SQRT_2); + psi_a_p3_m1 = simde_mm256_slli_epi16(psi_a_p3_m1, 2); + psi_a_p3_m3 = simde_mm256_mulhi_epi16(psi_a_p3_m3, ONE_OVER_SQRT_2); + psi_a_p3_m3 = simde_mm256_slli_epi16(psi_a_p3_m3, 2); + psi_a_p3_m5 = simde_mm256_mulhi_epi16(psi_a_p3_m5, ONE_OVER_SQRT_2); + psi_a_p3_m5 = simde_mm256_slli_epi16(psi_a_p3_m5, 2); + psi_a_p3_m7 = simde_mm256_mulhi_epi16(psi_a_p3_m7, ONE_OVER_SQRT_2); + psi_a_p3_m7 = simde_mm256_slli_epi16(psi_a_p3_m7, 2); + psi_a_p1_p7 = simde_mm256_mulhi_epi16(psi_a_p1_p7, ONE_OVER_SQRT_2); + psi_a_p1_p7 = simde_mm256_slli_epi16(psi_a_p1_p7, 2); + psi_a_p1_p5 = simde_mm256_mulhi_epi16(psi_a_p1_p5, ONE_OVER_SQRT_2); + psi_a_p1_p5 = simde_mm256_slli_epi16(psi_a_p1_p5, 2); + psi_a_p1_p3 = simde_mm256_mulhi_epi16(psi_a_p1_p3, ONE_OVER_SQRT_2); + psi_a_p1_p3 = simde_mm256_slli_epi16(psi_a_p1_p3, 2); + psi_a_p1_p1 = simde_mm256_mulhi_epi16(psi_a_p1_p1, ONE_OVER_SQRT_2); + psi_a_p1_p1 = simde_mm256_slli_epi16(psi_a_p1_p1, 2); + psi_a_p1_m1 = simde_mm256_mulhi_epi16(psi_a_p1_m1, ONE_OVER_SQRT_2); + psi_a_p1_m1 = simde_mm256_slli_epi16(psi_a_p1_m1, 2); + psi_a_p1_m3 = simde_mm256_mulhi_epi16(psi_a_p1_m3, ONE_OVER_SQRT_2); + psi_a_p1_m3 = simde_mm256_slli_epi16(psi_a_p1_m3, 2); + psi_a_p1_m5 = simde_mm256_mulhi_epi16(psi_a_p1_m5, ONE_OVER_SQRT_2); + psi_a_p1_m5 = simde_mm256_slli_epi16(psi_a_p1_m5, 2); + psi_a_p1_m7 = simde_mm256_mulhi_epi16(psi_a_p1_m7, ONE_OVER_SQRT_2); + psi_a_p1_m7 = simde_mm256_slli_epi16(psi_a_p1_m7, 2); + psi_a_m1_p7 = simde_mm256_mulhi_epi16(psi_a_m1_p7, ONE_OVER_SQRT_2); + psi_a_m1_p7 = simde_mm256_slli_epi16(psi_a_m1_p7, 2); + psi_a_m1_p5 = simde_mm256_mulhi_epi16(psi_a_m1_p5, ONE_OVER_SQRT_2); + psi_a_m1_p5 = simde_mm256_slli_epi16(psi_a_m1_p5, 2); + psi_a_m1_p3 = simde_mm256_mulhi_epi16(psi_a_m1_p3, ONE_OVER_SQRT_2); + psi_a_m1_p3 = simde_mm256_slli_epi16(psi_a_m1_p3, 2); + psi_a_m1_p1 = simde_mm256_mulhi_epi16(psi_a_m1_p1, ONE_OVER_SQRT_2); + psi_a_m1_p1 = simde_mm256_slli_epi16(psi_a_m1_p1, 2); + psi_a_m1_m1 = simde_mm256_mulhi_epi16(psi_a_m1_m1, ONE_OVER_SQRT_2); + psi_a_m1_m1 = simde_mm256_slli_epi16(psi_a_m1_m1, 2); + psi_a_m1_m3 = simde_mm256_mulhi_epi16(psi_a_m1_m3, ONE_OVER_SQRT_2); + psi_a_m1_m3 = simde_mm256_slli_epi16(psi_a_m1_m3, 2); + psi_a_m1_m5 = simde_mm256_mulhi_epi16(psi_a_m1_m5, ONE_OVER_SQRT_2); + psi_a_m1_m5 = simde_mm256_slli_epi16(psi_a_m1_m5, 2); + psi_a_m1_m7 = simde_mm256_mulhi_epi16(psi_a_m1_m7, ONE_OVER_SQRT_2); + psi_a_m1_m7 = simde_mm256_slli_epi16(psi_a_m1_m7, 2); + psi_a_m3_p7 = simde_mm256_mulhi_epi16(psi_a_m3_p7, ONE_OVER_SQRT_2); + psi_a_m3_p7 = simde_mm256_slli_epi16(psi_a_m3_p7, 2); + psi_a_m3_p5 = simde_mm256_mulhi_epi16(psi_a_m3_p5, ONE_OVER_SQRT_2); + psi_a_m3_p5 = simde_mm256_slli_epi16(psi_a_m3_p5, 2); + psi_a_m3_p3 = simde_mm256_mulhi_epi16(psi_a_m3_p3, ONE_OVER_SQRT_2); + psi_a_m3_p3 = simde_mm256_slli_epi16(psi_a_m3_p3, 2); + psi_a_m3_p1 = simde_mm256_mulhi_epi16(psi_a_m3_p1, ONE_OVER_SQRT_2); + psi_a_m3_p1 = simde_mm256_slli_epi16(psi_a_m3_p1, 2); + psi_a_m3_m1 = simde_mm256_mulhi_epi16(psi_a_m3_m1, ONE_OVER_SQRT_2); + psi_a_m3_m1 = simde_mm256_slli_epi16(psi_a_m3_m1, 2); + psi_a_m3_m3 = simde_mm256_mulhi_epi16(psi_a_m3_m3, ONE_OVER_SQRT_2); + psi_a_m3_m3 = simde_mm256_slli_epi16(psi_a_m3_m3, 2); + psi_a_m3_m5 = simde_mm256_mulhi_epi16(psi_a_m3_m5, ONE_OVER_SQRT_2); + psi_a_m3_m5 = simde_mm256_slli_epi16(psi_a_m3_m5, 2); + psi_a_m3_m7 = simde_mm256_mulhi_epi16(psi_a_m3_m7, ONE_OVER_SQRT_2); + psi_a_m3_m7 = simde_mm256_slli_epi16(psi_a_m3_m7, 2); + psi_a_m5_p7 = simde_mm256_mulhi_epi16(psi_a_m5_p7, ONE_OVER_SQRT_2); + psi_a_m5_p7 = simde_mm256_slli_epi16(psi_a_m5_p7, 2); + psi_a_m5_p5 = simde_mm256_mulhi_epi16(psi_a_m5_p5, ONE_OVER_SQRT_2); + psi_a_m5_p5 = simde_mm256_slli_epi16(psi_a_m5_p5, 2); + psi_a_m5_p3 = simde_mm256_mulhi_epi16(psi_a_m5_p3, ONE_OVER_SQRT_2); + psi_a_m5_p3 = simde_mm256_slli_epi16(psi_a_m5_p3, 2); + psi_a_m5_p1 = simde_mm256_mulhi_epi16(psi_a_m5_p1, ONE_OVER_SQRT_2); + psi_a_m5_p1 = simde_mm256_slli_epi16(psi_a_m5_p1, 2); + psi_a_m5_m1 = simde_mm256_mulhi_epi16(psi_a_m5_m1, ONE_OVER_SQRT_2); + psi_a_m5_m1 = simde_mm256_slli_epi16(psi_a_m5_m1, 2); + psi_a_m5_m3 = simde_mm256_mulhi_epi16(psi_a_m5_m3, ONE_OVER_SQRT_2); + psi_a_m5_m3 = simde_mm256_slli_epi16(psi_a_m5_m3, 2); + psi_a_m5_m5 = simde_mm256_mulhi_epi16(psi_a_m5_m5, ONE_OVER_SQRT_2); + psi_a_m5_m5 = simde_mm256_slli_epi16(psi_a_m5_m5, 2); + psi_a_m5_m7 = simde_mm256_mulhi_epi16(psi_a_m5_m7, ONE_OVER_SQRT_2); + psi_a_m5_m7 = simde_mm256_slli_epi16(psi_a_m5_m7, 2); + psi_a_m7_p7 = simde_mm256_mulhi_epi16(psi_a_m7_p7, ONE_OVER_SQRT_2); + psi_a_m7_p7 = simde_mm256_slli_epi16(psi_a_m7_p7, 2); + psi_a_m7_p5 = simde_mm256_mulhi_epi16(psi_a_m7_p5, ONE_OVER_SQRT_2); + psi_a_m7_p5 = simde_mm256_slli_epi16(psi_a_m7_p5, 2); + psi_a_m7_p3 = simde_mm256_mulhi_epi16(psi_a_m7_p3, ONE_OVER_SQRT_2); + psi_a_m7_p3 = simde_mm256_slli_epi16(psi_a_m7_p3, 2); + psi_a_m7_p1 = simde_mm256_mulhi_epi16(psi_a_m7_p1, ONE_OVER_SQRT_2); + psi_a_m7_p1 = simde_mm256_slli_epi16(psi_a_m7_p1, 2); + psi_a_m7_m1 = simde_mm256_mulhi_epi16(psi_a_m7_m1, ONE_OVER_SQRT_2); + psi_a_m7_m1 = simde_mm256_slli_epi16(psi_a_m7_m1, 2); + psi_a_m7_m3 = simde_mm256_mulhi_epi16(psi_a_m7_m3, ONE_OVER_SQRT_2); + psi_a_m7_m3 = simde_mm256_slli_epi16(psi_a_m7_m3, 2); + psi_a_m7_m5 = simde_mm256_mulhi_epi16(psi_a_m7_m5, ONE_OVER_SQRT_2); + psi_a_m7_m5 = simde_mm256_slli_epi16(psi_a_m7_m5, 2); + psi_a_m7_m7 = simde_mm256_mulhi_epi16(psi_a_m7_m7, ONE_OVER_SQRT_2); + psi_a_m7_m7 = simde_mm256_slli_epi16(psi_a_m7_m7, 2); + + // Calculation of a group of two terms in the bit metric involving squares of interference + square_a_64qam_epi16_256(a_r_p7_p7, a_i_p7_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_p7); + square_a_64qam_epi16_256(a_r_p7_p5, a_i_p7_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_p5); + square_a_64qam_epi16_256(a_r_p7_p3, a_i_p7_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_p3); + square_a_64qam_epi16_256(a_r_p7_p1, a_i_p7_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_p1); + square_a_64qam_epi16_256(a_r_p7_m1, a_i_p7_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_m1); + square_a_64qam_epi16_256(a_r_p7_m3, a_i_p7_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_m3); + square_a_64qam_epi16_256(a_r_p7_m5, a_i_p7_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_m5); + square_a_64qam_epi16_256(a_r_p7_m7, a_i_p7_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p7_m7); + square_a_64qam_epi16_256(a_r_p5_p7, a_i_p5_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_p7); + square_a_64qam_epi16_256(a_r_p5_p5, a_i_p5_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_p5); + square_a_64qam_epi16_256(a_r_p5_p3, a_i_p5_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_p3); + square_a_64qam_epi16_256(a_r_p5_p1, a_i_p5_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_p1); + square_a_64qam_epi16_256(a_r_p5_m1, a_i_p5_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_m1); + square_a_64qam_epi16_256(a_r_p5_m3, a_i_p5_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_m3); + square_a_64qam_epi16_256(a_r_p5_m5, a_i_p5_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_m5); + square_a_64qam_epi16_256(a_r_p5_m7, a_i_p5_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p5_m7); + square_a_64qam_epi16_256(a_r_p3_p7, a_i_p3_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_p7); + square_a_64qam_epi16_256(a_r_p3_p5, a_i_p3_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_p5); + square_a_64qam_epi16_256(a_r_p3_p3, a_i_p3_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_p3); + square_a_64qam_epi16_256(a_r_p3_p1, a_i_p3_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_p1); + square_a_64qam_epi16_256(a_r_p3_m1, a_i_p3_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_m1); + square_a_64qam_epi16_256(a_r_p3_m3, a_i_p3_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_m3); + square_a_64qam_epi16_256(a_r_p3_m5, a_i_p3_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_m5); + square_a_64qam_epi16_256(a_r_p3_m7, a_i_p3_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p3_m7); + square_a_64qam_epi16_256(a_r_p1_p7, a_i_p1_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_p7); + square_a_64qam_epi16_256(a_r_p1_p5, a_i_p1_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_p5); + square_a_64qam_epi16_256(a_r_p1_p3, a_i_p1_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_p3); + square_a_64qam_epi16_256(a_r_p1_p1, a_i_p1_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_p1); + square_a_64qam_epi16_256(a_r_p1_m1, a_i_p1_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_m1); + square_a_64qam_epi16_256(a_r_p1_m3, a_i_p1_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_m3); + square_a_64qam_epi16_256(a_r_p1_m5, a_i_p1_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_m5); + square_a_64qam_epi16_256(a_r_p1_m7, a_i_p1_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_p1_m7); + square_a_64qam_epi16_256(a_r_m1_p7, a_i_m1_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_p7); + square_a_64qam_epi16_256(a_r_m1_p5, a_i_m1_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_p5); + square_a_64qam_epi16_256(a_r_m1_p3, a_i_m1_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_p3); + square_a_64qam_epi16_256(a_r_m1_p1, a_i_m1_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_p1); + square_a_64qam_epi16_256(a_r_m1_m1, a_i_m1_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_m1); + square_a_64qam_epi16_256(a_r_m1_m3, a_i_m1_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_m3); + square_a_64qam_epi16_256(a_r_m1_m5, a_i_m1_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_m5); + square_a_64qam_epi16_256(a_r_m1_m7, a_i_m1_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m1_m7); + square_a_64qam_epi16_256(a_r_m3_p7, a_i_m3_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_p7); + square_a_64qam_epi16_256(a_r_m3_p5, a_i_m3_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_p5); + square_a_64qam_epi16_256(a_r_m3_p3, a_i_m3_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_p3); + square_a_64qam_epi16_256(a_r_m3_p1, a_i_m3_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_p1); + square_a_64qam_epi16_256(a_r_m3_m1, a_i_m3_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_m1); + square_a_64qam_epi16_256(a_r_m3_m3, a_i_m3_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_m3); + square_a_64qam_epi16_256(a_r_m3_m5, a_i_m3_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_m5); + square_a_64qam_epi16_256(a_r_m3_m7, a_i_m3_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m3_m7); + square_a_64qam_epi16_256(a_r_m5_p7, a_i_m5_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_p7); + square_a_64qam_epi16_256(a_r_m5_p5, a_i_m5_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_p5); + square_a_64qam_epi16_256(a_r_m5_p3, a_i_m5_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_p3); + square_a_64qam_epi16_256(a_r_m5_p1, a_i_m5_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_p1); + square_a_64qam_epi16_256(a_r_m5_m1, a_i_m5_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_m1); + square_a_64qam_epi16_256(a_r_m5_m3, a_i_m5_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_m3); + square_a_64qam_epi16_256(a_r_m5_m5, a_i_m5_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_m5); + square_a_64qam_epi16_256(a_r_m5_m7, a_i_m5_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m5_m7); + square_a_64qam_epi16_256(a_r_m7_p7, a_i_m7_p7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_p7); + square_a_64qam_epi16_256(a_r_m7_p5, a_i_m7_p5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_p5); + square_a_64qam_epi16_256(a_r_m7_p3, a_i_m7_p3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_p3); + square_a_64qam_epi16_256(a_r_m7_p1, a_i_m7_p1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_p1); + square_a_64qam_epi16_256(a_r_m7_m1, a_i_m7_m1, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_m1); + square_a_64qam_epi16_256(a_r_m7_m3, a_i_m7_m3, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_m3); + square_a_64qam_epi16_256(a_r_m7_m5, a_i_m7_m5, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_m5); + square_a_64qam_epi16_256(a_r_m7_m7, a_i_m7_m7, ch_mag_int, SQRT_42_OVER_FOUR, a_sq_m7_m7); + + // Computing different multiples of ||h0||^2 + // x=1, y=1 + ch_mag_2_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, ONE_OVER_FOUR_SQRT_42); + ch_mag_2_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_2_over_42_with_sigma2, 1); + // x=1, y=3 + ch_mag_10_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, FIVE_OVER_FOUR_SQRT_42); + ch_mag_10_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_10_over_42_with_sigma2, 1); + // x=1, x=5 + ch_mag_26_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, THIRTEEN_OVER_FOUR_SQRT_42); + ch_mag_26_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_26_over_42_with_sigma2, 1); + // x=1, y=7 + ch_mag_50_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, TWENTYFIVE_OVER_FOUR_SQRT_42); + ch_mag_50_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_50_over_42_with_sigma2, 1); + // x=3, y=3 + ch_mag_18_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, NINE_OVER_FOUR_SQRT_42); + ch_mag_18_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_18_over_42_with_sigma2, 1); + // x=3, y=5 + ch_mag_34_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, SEVENTEEN_OVER_FOUR_SQRT_42); + ch_mag_34_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_34_over_42_with_sigma2, 1); + // x=3, y=7 + ch_mag_58_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, TWENTYNINE_OVER_FOUR_SQRT_42); + ch_mag_58_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_58_over_42_with_sigma2, 2); + // x=5, y=5 + ch_mag_50_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, TWENTYFIVE_OVER_FOUR_SQRT_42); + ch_mag_50_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_50_over_42_with_sigma2, 1); + // x=5, y=7 + ch_mag_74_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, THIRTYSEVEN_OVER_FOUR_SQRT_42); + ch_mag_74_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_74_over_42_with_sigma2, 2); + // x=7, y=7 + ch_mag_98_over_42_with_sigma2 = simde_mm256_mulhi_epi16(ch_mag_des, FORTYNINE_OVER_FOUR_SQRT_42); + ch_mag_98_over_42_with_sigma2 = simde_mm256_slli_epi16(ch_mag_98_over_42_with_sigma2, 2); + + // Computing Metrics + xmm0 = simde_mm256_subs_epi16(psi_a_p7_p7, a_sq_p7_p7); + simde__m256i xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_7_7); + simde__m256i bit_met_p7_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_98_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_p5, a_sq_p7_p5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_7_5); + simde__m256i bit_met_p7_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_p3, a_sq_p7_p3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_7_3); + simde__m256i bit_met_p7_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_p1, a_sq_p7_p1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_7_1); + simde__m256i bit_met_p7_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_m1, a_sq_p7_m1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_7_1); + simde__m256i bit_met_p7_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_m3, a_sq_p7_m3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_7_3); + simde__m256i bit_met_p7_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_m5, a_sq_p7_m5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_7_5); + simde__m256i bit_met_p7_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p7_m7, a_sq_p7_m7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_7_7); + simde__m256i bit_met_p7_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_98_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_p7, a_sq_p5_p7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_5_7); + simde__m256i bit_met_p5_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_p5, a_sq_p5_p5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_5_5); + simde__m256i bit_met_p5_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_p3, a_sq_p5_p3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_5_3); + simde__m256i bit_met_p5_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_p1, a_sq_p5_p1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_5_1); + simde__m256i bit_met_p5_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_m1, a_sq_p5_m1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_5_1); + simde__m256i bit_met_p5_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_m3, a_sq_p5_m3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_5_3); + simde__m256i bit_met_p5_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_m5, a_sq_p5_m5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_5_5); + simde__m256i bit_met_p5_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p5_m7, a_sq_p5_m7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_5_7); + simde__m256i bit_met_p5_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_p7, a_sq_p3_p7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_3_7); + simde__m256i bit_met_p3_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_p5, a_sq_p3_p5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_3_5); + simde__m256i bit_met_p3_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_p3, a_sq_p3_p3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_3_3); + simde__m256i bit_met_p3_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_18_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_p1, a_sq_p3_p1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_3_1); + simde__m256i bit_met_p3_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_m1, a_sq_p3_m1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_3_1); + simde__m256i bit_met_p3_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_m3, a_sq_p3_m3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_3_3); + simde__m256i bit_met_p3_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_18_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_m5, a_sq_p3_m5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_3_5); + simde__m256i bit_met_p3_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p3_m7, a_sq_p3_m7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_3_7); + simde__m256i bit_met_p3_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_p7, a_sq_p1_p7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_1_7); + simde__m256i bit_met_p1_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_p5, a_sq_p1_p5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_1_5); + simde__m256i bit_met_p1_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_p3, a_sq_p1_p3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_1_3); + simde__m256i bit_met_p1_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_p1, a_sq_p1_p1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_p_1_1); + simde__m256i bit_met_p1_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_2_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_m1, a_sq_p1_m1); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_1_1); + simde__m256i bit_met_p1_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_2_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_m3, a_sq_p1_m3); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_1_3); + simde__m256i bit_met_p1_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_m5, a_sq_p1_m5); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_1_5); + simde__m256i bit_met_p1_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_p1_m7, a_sq_p1_m7); + xmm1 = simde_mm256_adds_epi16(xmm0, y0_m_1_7); + simde__m256i bit_met_p1_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + + xmm0 = simde_mm256_subs_epi16(psi_a_m1_p7, a_sq_m1_p7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_1_7); + simde__m256i bit_met_m1_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_p5, a_sq_m1_p5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_1_5); + simde__m256i bit_met_m1_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_p3, a_sq_m1_p3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_1_3); + simde__m256i bit_met_m1_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_p1, a_sq_m1_p1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_1_1); + simde__m256i bit_met_m1_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_2_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_m1, a_sq_m1_m1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_1_1); + simde__m256i bit_met_m1_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_2_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_m3, a_sq_m1_m3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_1_3); + simde__m256i bit_met_m1_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_m5, a_sq_m1_m5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_1_5); + simde__m256i bit_met_m1_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m1_m7, a_sq_m1_m7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_1_7); + simde__m256i bit_met_m1_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_p7, a_sq_m3_p7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_3_7); + simde__m256i bit_met_m3_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_p5, a_sq_m3_p5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_3_5); + simde__m256i bit_met_m3_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_p3, a_sq_m3_p3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_3_3); + simde__m256i bit_met_m3_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_18_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_p1, a_sq_m3_p1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_3_1); + simde__m256i bit_met_m3_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_m1, a_sq_m3_m1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_3_1); + simde__m256i bit_met_m3_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_10_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_m3, a_sq_m3_m3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_3_3); + simde__m256i bit_met_m3_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_18_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_m5, a_sq_m3_m5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_3_5); + simde__m256i bit_met_m3_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m3_m7, a_sq_m3_m7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_3_7); + simde__m256i bit_met_m3_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_p7, a_sq_m5_p7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_5_7); + simde__m256i bit_met_m5_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_p5, a_sq_m5_p5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_5_5); + simde__m256i bit_met_m5_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_p3, a_sq_m5_p3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_5_3); + simde__m256i bit_met_m5_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_p1, a_sq_m5_p1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_5_1); + simde__m256i bit_met_m5_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_m1, a_sq_m5_m1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_5_1); + simde__m256i bit_met_m5_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_26_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_m3, a_sq_m5_m3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_5_3); + simde__m256i bit_met_m5_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_34_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_m5, a_sq_m5_m5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_5_5); + simde__m256i bit_met_m5_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m5_m7, a_sq_m5_m7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_5_7); + simde__m256i bit_met_m5_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_p7, a_sq_m7_p7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_7_7); + simde__m256i bit_met_m7_p7 = simde_mm256_subs_epi16(xmm1, ch_mag_98_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_p5, a_sq_m7_p5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_7_5); + simde__m256i bit_met_m7_p5 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_p3, a_sq_m7_p3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_7_3); + simde__m256i bit_met_m7_p3 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_p1, a_sq_m7_p1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_m_7_1); + simde__m256i bit_met_m7_p1 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_m1, a_sq_m7_m1); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_7_1); + simde__m256i bit_met_m7_m1 = simde_mm256_subs_epi16(xmm1, ch_mag_50_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_m3, a_sq_m7_m3); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_7_3); + simde__m256i bit_met_m7_m3 = simde_mm256_subs_epi16(xmm1, ch_mag_58_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_m5, a_sq_m7_m5); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_7_5); + simde__m256i bit_met_m7_m5 = simde_mm256_subs_epi16(xmm1, ch_mag_74_over_42_with_sigma2); + xmm0 = simde_mm256_subs_epi16(psi_a_m7_m7, a_sq_m7_m7); + xmm1 = simde_mm256_subs_epi16(xmm0, y0_p_7_7); + simde__m256i bit_met_m7_m7 = simde_mm256_subs_epi16(xmm1, ch_mag_98_over_42_with_sigma2); + + // Detection for 1st bit + // bit = 1 + xmm0 = simde_mm256_max_epi16(bit_met_m7_p7, bit_met_m7_p5); + xmm1 = simde_mm256_max_epi16(bit_met_m7_p3, bit_met_m7_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m7_m1, bit_met_m7_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m7_m5, bit_met_m7_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + simde__m256i logmax_den_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m5_p7, bit_met_m5_p5); + xmm1 = simde_mm256_max_epi16(bit_met_m5_p3, bit_met_m5_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m5_m1, bit_met_m5_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m5, bit_met_m5_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m3_p7, bit_met_m3_p5); + xmm1 = simde_mm256_max_epi16(bit_met_m3_p3, bit_met_m3_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m3_m1, bit_met_m3_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m3_m5, bit_met_m3_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m1_p7, bit_met_m1_p5); + xmm1 = simde_mm256_max_epi16(bit_met_m1_p3, bit_met_m1_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m1, bit_met_m1_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m1_m5, bit_met_m1_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + + // bit = 0 + xmm0 = simde_mm256_max_epi16(bit_met_p7_p7, bit_met_p7_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p7_p3, bit_met_p7_p1); + xmm2 = simde_mm256_max_epi16(bit_met_p7_m1, bit_met_p7_m3); + xmm3 = simde_mm256_max_epi16(bit_met_p7_m5, bit_met_p7_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + simde__m256i logmax_num_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p5_p7, bit_met_p5_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p5_p3, bit_met_p5_p1); + xmm2 = simde_mm256_max_epi16(bit_met_p5_m1, bit_met_p5_m3); + xmm3 = simde_mm256_max_epi16(bit_met_p5_m5, bit_met_p5_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p3_p7, bit_met_p3_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p3, bit_met_p3_p1); + xmm2 = simde_mm256_max_epi16(bit_met_p3_m1, bit_met_p3_m3); + xmm3 = simde_mm256_max_epi16(bit_met_p3_m5, bit_met_p3_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p1_p7, bit_met_p1_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p1_p3, bit_met_p1_p1); + xmm2 = simde_mm256_max_epi16(bit_met_p1_m1, bit_met_p1_m3); + xmm3 = simde_mm256_max_epi16(bit_met_p1_m5, bit_met_p1_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + + y0r = simde_mm256_subs_epi16(logmax_num_re0, logmax_den_re0); + + // Detection for 2nd bit + // bit = 1 + xmm0 = simde_mm256_max_epi16(bit_met_p7_m1, bit_met_p5_m1); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m1, bit_met_p1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m1, bit_met_m3_m1); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m1, bit_met_m7_m1); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m3, bit_met_p5_m3); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m3, bit_met_p1_m3); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m3, bit_met_m3_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m3, bit_met_m7_m3); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m5, bit_met_p5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m5, bit_met_p1_m5); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m5, bit_met_m3_m5); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m5, bit_met_m7_m5); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m7, bit_met_p5_m7); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m7, bit_met_p1_m7); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m7, bit_met_m3_m7); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m7, bit_met_m7_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + + // bit = 0 + xmm0 = simde_mm256_max_epi16(bit_met_p7_p1, bit_met_p5_p1); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p1, bit_met_p1_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p1, bit_met_m3_p1); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p1, bit_met_m7_p1); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p3, bit_met_p5_p3); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p3, bit_met_p1_p3); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p3, bit_met_m3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p3, bit_met_m7_p3); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p5, bit_met_p5_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p5, bit_met_p1_p5); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p5, bit_met_m3_p5); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p5, bit_met_m7_p5); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p7, bit_met_p5_p7); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p7, bit_met_p1_p7); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p7, bit_met_m3_p7); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p7, bit_met_m7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + + y1r = simde_mm256_subs_epi16(logmax_num_re0, logmax_den_re0); + + // Detection for 3rd bit + xmm0 = simde_mm256_max_epi16(bit_met_m7_m7, bit_met_m7_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m7_m3, bit_met_m7_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m7_p1, bit_met_m7_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m7_p5, bit_met_m7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m5_m7, bit_met_m5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m5_m3, bit_met_m5_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m5_p1, bit_met_m5_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p5, bit_met_m5_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p5_m7, bit_met_p5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p5_m3, bit_met_p5_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p5_p1, bit_met_p5_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p5_p5, bit_met_p5_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m7, bit_met_p7_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p7_m3, bit_met_p7_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p7_p1, bit_met_p7_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p7_p5, bit_met_p7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + + xmm0 = simde_mm256_max_epi16(bit_met_m3_m7, bit_met_m3_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m3_m3, bit_met_m3_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m3_p1, bit_met_m3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m3_p5, bit_met_m3_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m1_m7, bit_met_m1_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m1_m3, bit_met_m1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p1, bit_met_m1_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m1_p5, bit_met_m1_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p1_m7, bit_met_p1_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p1_m3, bit_met_p1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p1_p1, bit_met_p1_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p1_p5, bit_met_p1_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p3_m7, bit_met_p3_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m3, bit_met_p3_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p3_p1, bit_met_p3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p3_p5, bit_met_p3_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + + simde__m256i y2r = simde_mm256_subs_epi16(logmax_num_re0, logmax_den_re0); + + // Detection for 4th bit + xmm0 = simde_mm256_max_epi16(bit_met_p7_p7, bit_met_p5_p7); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p7, bit_met_p1_p7); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p7, bit_met_m3_p7); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p7, bit_met_m7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p5, bit_met_p5_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p5, bit_met_p1_p5); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p5, bit_met_m3_p5); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p5, bit_met_m5_p5); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m5, bit_met_p5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m5, bit_met_p1_m5); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m5, bit_met_m3_m5); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m5, bit_met_m7_m5); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m7, bit_met_p5_m7); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m7, bit_met_p1_m7); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m7, bit_met_m3_m7); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m7, bit_met_m7_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + + xmm0 = simde_mm256_max_epi16(bit_met_p7_m1, bit_met_p5_m1); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m1, bit_met_p1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m1, bit_met_m3_m1); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m1, bit_met_m7_m1); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m3, bit_met_p5_m3); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m3, bit_met_p1_m3); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m3, bit_met_m3_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m3, bit_met_m7_m3); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p1, bit_met_p5_p1); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p1, bit_met_p1_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p1, bit_met_m3_p1); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p1, bit_met_m7_p1); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p3, bit_met_p5_p3); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p3, bit_met_p1_p3); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p3, bit_met_m3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p3, bit_met_m7_p3); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + + y0i = simde_mm256_subs_epi16(logmax_num_re0, logmax_den_re0); + + // Detection for 5th bit + xmm0 = simde_mm256_max_epi16(bit_met_m7_m7, bit_met_m7_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m7_m3, bit_met_m7_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m7_p1, bit_met_m7_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m7_p5, bit_met_m7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m1_m7, bit_met_m1_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m1_m3, bit_met_m1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p1, bit_met_m1_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m1_p5, bit_met_m1_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p1_m7, bit_met_p1_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p1_m3, bit_met_p1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p1_p1, bit_met_p1_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p1_p5, bit_met_p1_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m7, bit_met_p7_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p7_m3, bit_met_p7_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p7_p1, bit_met_p7_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p7_p5, bit_met_p7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + + xmm0 = simde_mm256_max_epi16(bit_met_m5_m7, bit_met_m5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m5_m3, bit_met_m5_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m5_p1, bit_met_m5_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p5, bit_met_m5_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_m3_m7, bit_met_m3_m5); + xmm1 = simde_mm256_max_epi16(bit_met_m3_m3, bit_met_m3_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m3_p1, bit_met_m3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m3_p5, bit_met_m3_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p3_m7, bit_met_p3_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m3, bit_met_p3_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p3_p1, bit_met_p3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p3_p5, bit_met_p3_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p5_m7, bit_met_p5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p5_m3, bit_met_p5_m1); + xmm2 = simde_mm256_max_epi16(bit_met_p5_p1, bit_met_p5_p3); + xmm3 = simde_mm256_max_epi16(bit_met_p5_p5, bit_met_p5_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + + y1i = simde_mm256_subs_epi16(logmax_num_re0, logmax_den_re0); + + // Detection for 6th bit + xmm0 = simde_mm256_max_epi16(bit_met_p7_p7, bit_met_p5_p7); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p7, bit_met_p1_p7); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p7, bit_met_m3_p7); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p7, bit_met_m7_p7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p1, bit_met_p5_p1); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p1, bit_met_p1_p1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p1, bit_met_m3_p1); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p1, bit_met_m5_p1); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m1, bit_met_p5_m1); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m1, bit_met_p1_m1); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m1, bit_met_m3_m1); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m1, bit_met_m7_m1); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m7, bit_met_p5_m7); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m7, bit_met_p1_m7); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m7, bit_met_m3_m7); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m7, bit_met_m7_m7); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm4); + logmax_den_re0 = simde_mm256_max_epi16(logmax_den_re0, xmm5); + + xmm0 = simde_mm256_max_epi16(bit_met_p7_m5, bit_met_p5_m5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m5, bit_met_p1_m5); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m5, bit_met_m3_m5); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m5, bit_met_m7_m5); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(xmm4, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_m3, bit_met_p5_m3); + xmm1 = simde_mm256_max_epi16(bit_met_p3_m3, bit_met_p1_m3); + xmm2 = simde_mm256_max_epi16(bit_met_m1_m3, bit_met_m3_m3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_m3, bit_met_m7_m3); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p3, bit_met_p5_p3); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p3, bit_met_p1_p3); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p3, bit_met_m3_p3); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p3, bit_met_m7_p3); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + xmm0 = simde_mm256_max_epi16(bit_met_p7_p5, bit_met_p5_p5); + xmm1 = simde_mm256_max_epi16(bit_met_p3_p5, bit_met_p1_p5); + xmm2 = simde_mm256_max_epi16(bit_met_m1_p5, bit_met_m3_p5); + xmm3 = simde_mm256_max_epi16(bit_met_m5_p5, bit_met_m7_p5); + xmm4 = simde_mm256_max_epi16(xmm0, xmm1); + xmm5 = simde_mm256_max_epi16(xmm2, xmm3); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm4); + logmax_num_re0 = simde_mm256_max_epi16(logmax_num_re0, xmm5); + + simde__m256i y2i = simde_mm256_subs_epi16(logmax_num_re0, logmax_den_re0); + + // Map to output stream, difficult to do in SIMD since we have 6 16bit LLRs + int idx0 = 24 * i; + for (int re = 0; re < 16; re++) { + stream0_out[idx0 + 0].r = ((short *)&y0r)[re]; + stream0_out[idx0 + 0].i = ((short *)&y1r)[re]; + stream0_out[idx0 + 1].r = ((short *)&y2r)[re]; + stream0_out[idx0 + 1].i = ((short *)&y0i)[re]; + stream0_out[idx0 + 2].r = ((short *)&y1i)[re]; + stream0_out[idx0 + 2].i = ((short *)&y2i)[re]; + idx0 += 3; + } + } + + _mm_empty(); + _m_empty(); +} + void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, int32_t **ul_ch_mag, int32_t ***rho, @@ -1407,7 +4031,9 @@ void nr_ulsch_compute_ML_llr(int32_t **rxdataF_comp, nr_ulsch_qam16_qam16(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re); break; case 6: - AssertFatal(1 == 0, "LLR computation is not implemented yet for ML with Qm = %d\n", mod_order); + nr_ulsch_qam64_qam64(rxdataF_comp0, rxdataF_comp1, ul_ch_mag0, ul_ch_mag1, llr_layers0, rho0, nb_re); + nr_ulsch_qam64_qam64(rxdataF_comp1, rxdataF_comp0, ul_ch_mag1, ul_ch_mag0, llr_layers1, rho1, nb_re); + break; default: AssertFatal(1 == 0, "nr_ulsch_compute_llr: invalid Qm value, symbol = %d, Qm = %d\n", symbol, mod_order); } From 917ff8e97b6843519d1da886f808a1174381f7d7 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Wed, 26 Apr 2023 15:22:43 +0100 Subject: [PATCH 10/19] Remove duplicated code --- CMakeLists.txt | 6 +- .../dlsch_llr_computation_avx2.c | 48 ++---- .../NR_TRANSPORT/nr_ulsch_llr_computation.c | 154 +++--------------- openair1/PHY/TOOLS/simde_operations.c | 60 +++++++ openair1/PHY/TOOLS/tools_defs.h | 2 + 5 files changed, 96 insertions(+), 174 deletions(-) create mode 100644 openair1/PHY/TOOLS/simde_operations.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 214a16b79a..2c1b7d6421 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1071,6 +1071,7 @@ set(PHY_SRC_COMMON ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c ${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c ${OPENAIR1_DIR}/PHY/TOOLS/lut.c + ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c ) set(PHY_SRC @@ -1206,6 +1207,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c ${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c ${OPENAIR1_DIR}/PHY/TOOLS/lut.c + ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c ${PHY_POLARSRC} ${PHY_SMALLBLOCKSRC} ${PHY_NR_CODINGIF} @@ -1258,6 +1260,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c ${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c ${OPENAIR1_DIR}/PHY/TOOLS/lut.c + ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c ${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c # ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c ${PHY_POLARSRC} @@ -1306,8 +1309,9 @@ set(PHY_MEX_UE ${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_sv.c ${OPENAIR1_DIR}/PHY/TOOLS/cmult_vv.c - ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c + ${OPENAIR1_DIR}/PHY/TOOLS/simde_operations.c + ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ue_measurements.c ${OPENAIR_DIR}/common/utils/LOG/log.c ${OPENAIR_DIR}/common/utils/T/T.c diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c index c00040f668..88d7dfef6b 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c @@ -121,34 +121,6 @@ tmp_result2 = simde_mm256_slli_epi16(tmp_result2, 1); \ const simde__m256i a_sq = simde_mm256_adds_epi16(tmp_result, tmp_result2); - void seperate_real_imag_parts(__m256i *out_re, __m256i *out_im, __m256i in0, __m256i in1) - { - __m256i tmp0; - __m256i tmp1; - - in0 = simde_mm256_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm256_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm256_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - in1 = simde_mm256_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm256_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm256_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // in0 = [Re(0,1,2,3) Im(0,1,2,3) Re(4,5,6,7) Im(4,5,6,7)] - // in0 = [Re(8,9,10,11) Im(8,9,10,11) Re(12,13,14,15) Im(12,13,14,15)] - - tmp0 = simde_mm256_unpacklo_epi64(in0, in1); - // axmm2 = [Re(0,1,2,3) Re(8,9,10,11) Re(4,5,6,7) Re(12,13,14,15)] - tmp0 = simde_mm256_permute4x64_epi64(tmp0, 0xd8); // Re(rho) - - tmp1 = simde_mm256_unpackhi_epi64(in0, in1); - // axmm3 = [Im(0,1,2,3) Im(8,9,10,11) Im(4,5,6,7) Im(12,13,14,15)] - tmp1 = simde_mm256_permute4x64_epi64(tmp1, 0xd8); // Im(rho) - - *out_re = tmp0; - *out_im = tmp1; -} - void qam64_qam16_avx2(short *stream0_in, short *stream1_in, short *ch_mag, @@ -245,7 +217,7 @@ void qam64_qam16_avx2(short *stream0_in, xmm3 = _mm_unpackhi_epi64(xmm0,xmm1); // Im(rho) */ simde__m256i xmm0, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; - seperate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i+1]); + simde_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i+1]); const simde__m256i rho_rpi = simde_mm256_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) const simde__m256i rho_rmi = simde_mm256_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -323,7 +295,7 @@ void qam64_qam16_avx2(short *stream0_in, */ simde__m256i y1r, y1i; - seperate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i+1]); + simde_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i+1]); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(0));// ZERO for abs_pi16 @@ -604,7 +576,7 @@ void qam64_qam16_avx2(short *stream0_in, y0i = simde_mm256_unpackhi_epi64(xmm0,xmm1); */ simde__m256i y0r, y0i; - seperate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i+1]); + simde_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i+1]); /* // Rearrange desired channel magnitudes @@ -619,7 +591,7 @@ void qam64_qam16_avx2(short *stream0_in, ch_mag_des = simde_mm256_unpacklo_epi64(xmm2,xmm3); */ - seperate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i+1]); + simde_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i+1]); // Rearrange interfering channel magnitudes /* @@ -634,7 +606,7 @@ void qam64_qam16_avx2(short *stream0_in, ch_mag_int = simde_mm256_unpacklo_epi64(xmm2,xmm3); */ - seperate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i+1]); + simde_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i+1]); y0r_one_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, THREE_OVER_SQRT_42); @@ -1819,7 +1791,7 @@ void qam64_qam64_avx2(int32_t *stream0_in, xmm3 = simde_mm256_permute4x64_epi64(xmm3,0xd8); // Im(rho) */ simde__m256i xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; - seperate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i+1]); + simde_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i+1]); simde__m256i rho_rpi = simde_mm256_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m256i rho_rmi = simde_mm256_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1899,7 +1871,7 @@ void qam64_qam64_avx2(int32_t *stream0_in, y1i = simde_mm256_permute4x64_epi64(y1i,0xd8); // Im(y1) */ simde__m256i y1r, y1i, xmm0; - seperate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i+1]); + simde_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i+1]); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(0));// ZERO for abs_pi16 @@ -2181,7 +2153,7 @@ void qam64_qam64_avx2(int32_t *stream0_in, y0i = _mm_unpackhi_epi64(xmm0,xmm1); */ simde__m256i y0r, y0i; - seperate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i+1]); + simde_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i+1]); // Rearrange desired channel magnitudes // [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2),...,,|h|^2(7),|h|^2(7)]*(2/sqrt(10)) @@ -2197,7 +2169,7 @@ void qam64_qam64_avx2(int32_t *stream0_in, ch_mag_des = _mm_unpacklo_epi64(xmm2,xmm3); */ // xmm2 is dummy variable that contains the same values as ch_mag_des - seperate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i+1]); + simde_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i+1]); // Rearrange interfering channel magnitudes @@ -2212,7 +2184,7 @@ void qam64_qam64_avx2(int32_t *stream0_in, xmm3 = _mm_shuffle_epi32(xmm3,0xd8); //_MM_SHUFFLE(0,2,1,3)); ch_mag_int = _mm_unpacklo_epi64(xmm2,xmm3); */ - seperate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i+1]); + simde_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i+1]); y0r_one_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, THREE_OVER_SQRT_42); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c index 0ecadd6646..f378830c23 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c @@ -535,62 +535,22 @@ void nr_ulsch_qpsk_qpsk(c16_t *stream0_in, c16_t *stream1_in, c16_t *stream0_out for (int i = 0; i < length >> 2; i += 2) { /// Compute real and imaginary parts of MF output for stream 0 (desired stream) - - // Put xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - __m128i xmm0 = stream0_128i_in[i]; // 4 symbols - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - __m128i xmm1 = stream0_128i_in[i + 1]; // 4 symbols - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - __m128i y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // y0r = Re(y0) - __m128i y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); // y0i = Im(y0) - + __m128i y0r, y0i; + simde_mm128_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); __m128i y0r_over2 = simde_mm_mulhi_epi16(y0r, ONE_OVER_2_SQRT_2); y0r_over2 = _mm_slli_epi16(y0r_over2, 1); // y0r_over2 = Re(y0) / sqrt(2) __m128i y0i_over2 = simde_mm_mulhi_epi16(y0i, ONE_OVER_2_SQRT_2); y0i_over2 = _mm_slli_epi16(y0i_over2, 1); // y0i_over2 = Im(y0) / sqrt(2) /// Compute real and imaginary parts of MF output for stream 1 (interference stream) - - // Put xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - xmm0 = stream1_128i_in[i]; // 4 symbols - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - xmm1 = stream1_128i_in[i + 1]; // 4 symbols - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - __m128i y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); // y1r = Re(y1) - __m128i y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); // y1i = Im(y1) - __m128i y1r_over2 = simde_mm_srai_epi16(y1r, 1); // y1r_over2 = Re(y1) / 2 - __m128i y1i_over2 = simde_mm_srai_epi16(y1i, 1); // y1i_over2 = Im(y1) / 2 + __m128i y1r_over2, y1i_over2; + simde_mm128_separate_real_imag_parts(&y1r_over2, &y1i_over2, stream1_128i_in[i], stream1_128i_in[i + 1]); + y1r_over2 = simde_mm_srai_epi16(y1r_over2, 1); // y1r_over2 = Re(y1) / 2 + y1i_over2 = simde_mm_srai_epi16(y1i_over2, 1); // y1i_over2 = Im(y1) / 2 /// Get real and imaginary parts of rho - - // Put xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - xmm0 = rho01_128i[i]; // 4 symbols - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - xmm1 = rho01_128i[i + 1]; // 4 symbols - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - __m128i rhor = simde_mm_unpacklo_epi64(xmm0, xmm1); // rhor = Re(rho) - __m128i rhoi = simde_mm_unpackhi_epi64(xmm0, xmm1); // rhoi = Im(rho) + __m128i rhor, rhoi; + simde_mm128_separate_real_imag_parts(&rhor, &rhoi, rho01_128i[i], rho01_128i[i + 1]); /// Compute |psi_r| and |psi_i| @@ -951,18 +911,7 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, for (int i = 0; i < length >> 2; i += 2) { // Get rho - xmm0 = rho01_128i[i]; - xmm1 = rho01_128i[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - // xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - // xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - xmm2 = simde_mm_unpacklo_epi64(xmm0, xmm1); // Re(rho) - xmm3 = simde_mm_unpackhi_epi64(xmm0, xmm1); // Im(rho) + simde_mm128_separate_real_imag_parts(&xmm2, &xmm3, rho01_128i[i], rho01_128i[i + 1]); rho_rpi = simde_mm_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) rho_rmi = simde_mm_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -989,18 +938,7 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, rho_rmi_3_1 = simde_mm_subs_epi16(xmm6, xmm7); // Rearrange interfering MF output - xmm0 = stream1_128i_in[i]; - xmm1 = stream1_128i_in[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - // xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - // xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - y1r = simde_mm_unpacklo_epi64(xmm0, xmm1); //[y1r(1),y1r(2),y1r(3),y1r(4)] - y1i = simde_mm_unpackhi_epi64(xmm0, xmm1); //[y1i(1),y1i(2),y1i(3),y1i(4)] + simde_mm128_separate_real_imag_parts(&y1r, &y1i, stream1_128i_in[i], stream1_128i_in[i + 1]); xmm0 = simde_mm_setzero_si128(); // ZERO xmm2 = simde_mm_subs_epi16(rho_rpi_1_1, y1r); // = [Re(rho)+ Im(rho)]/sqrt(10) - y1r @@ -1070,43 +1008,14 @@ void nr_ulsch_qam16_qam16(c16_t *stream0_in, psi_i_m3_m3 = simde_mm_abs_epi16(xmm2); // Rearrange desired MF output - xmm0 = stream0_128i_in[i]; - xmm1 = stream0_128i_in[i + 1]; - xmm0 = simde_mm_shufflelo_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shufflehi_epi16(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm0 = simde_mm_shuffle_epi32(xmm0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflelo_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shufflehi_epi16(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm1 = simde_mm_shuffle_epi32(xmm1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - // xmm0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] - // xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] - y0r = simde_mm_unpacklo_epi64(xmm0, xmm1); // = [y0r(1),y0r(2),y0r(3),y0r(4)] - y0i = simde_mm_unpackhi_epi64(xmm0, xmm1); + simde_mm128_separate_real_imag_parts(&y0r, &y0i, stream0_128i_in[i], stream0_128i_in[i + 1]); // Rearrange desired channel magnitudes - xmm2 = ch_mag_128i[i]; // = [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2)]*(2/sqrt(10)) - xmm3 = ch_mag_128i[i + 1]; // = [|h|^2(3),|h|^2(3),|h|^2(4),|h|^2(4)]*(2/sqrt(10)) - xmm2 = simde_mm_shufflelo_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - ch_mag_des = simde_mm_unpacklo_epi64(xmm2, xmm3); // = [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) + // [|h|^2(1),|h|^2(2),|h|^2(3),|h|^2(4)]*(2/sqrt(10)) + simde_mm128_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_128i[i], ch_mag_128i[i + 1]); // Rearrange interfering channel magnitudes - xmm2 = ch_mag_128i_i[i]; - xmm3 = ch_mag_128i_i[i + 1]; - - xmm2 = simde_mm_shufflelo_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shufflehi_epi16(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm2 = simde_mm_shuffle_epi32(xmm2, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflelo_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shufflehi_epi16(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - xmm3 = simde_mm_shuffle_epi32(xmm3, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - ch_mag_int = simde_mm_unpacklo_epi64(xmm2, xmm3); + simde_mm128_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_128i_i[i], ch_mag_128i_i[i + 1]); // Scale MF output of desired signal y0r_over_sqrt10 = simde_mm_mulhi_epi16(y0r, ONE_OVER_SQRT_10); @@ -1437,31 +1346,6 @@ static const int16_t ones256[16] __attribute__((aligned(32))) = {0xffff, tmp_result2 = simde_mm256_slli_epi16(tmp_result2, 1); \ const simde__m256i a_sq = simde_mm256_adds_epi16(tmp_result, tmp_result2); -void separate_real_imag_parts(__m256i *out_re, __m256i *out_im, __m256i in0, __m256i in1) -{ - in0 = simde_mm256_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm256_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in0 = simde_mm256_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - in1 = simde_mm256_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm256_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - in1 = simde_mm256_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); - - // in0 = [Re(0,1,2,3) Im(0,1,2,3) Re(4,5,6,7) Im(4,5,6,7)] - // in0 = [Re(8,9,10,11) Im(8,9,10,11) Re(12,13,14,15) Im(12,13,14,15)] - - __m256i tmp0 = simde_mm256_unpacklo_epi64(in0, in1); - // axmm2 = [Re(0,1,2,3) Re(8,9,10,11) Re(4,5,6,7) Re(12,13,14,15)] - tmp0 = simde_mm256_permute4x64_epi64(tmp0, 0xd8); // Re(rho) - - __m256i tmp1 = simde_mm256_unpackhi_epi64(in0, in1); - // axmm3 = [Im(0,1,2,3) Im(8,9,10,11) Im(4,5,6,7) Im(12,13,14,15)] - tmp1 = simde_mm256_permute4x64_epi64(tmp1, 0xd8); // Im(rho) - - *out_re = tmp0; - *out_im = tmp1; -} - /* * This function computes the LLRs of stream 0 (s_0) in presence of the interfering stream 1 (s_1) assuming that both symbols are * 64QAM. It can be used for both MU-MIMO interference-aware receiver or for SU-MIMO receivers. @@ -1540,7 +1424,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Get rho simde__m256i xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8; - separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); + simde_mm256_separate_real_imag_parts(&xmm2, &xmm3, rho01_256i[i], rho01_256i[i + 1]); simde__m256i rho_rpi = simde_mm256_adds_epi16(xmm2, xmm3); // rho = Re(rho) + Im(rho) simde__m256i rho_rmi = simde_mm256_subs_epi16(xmm2, xmm3); // rho* = Re(rho) - Im(rho) @@ -1603,7 +1487,7 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Rearrange interfering MF output simde__m256i y1r, y1i, xmm0; - separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); + simde_mm256_separate_real_imag_parts(&y1r, &y1i, stream1_256i_in[i], stream1_256i_in[i + 1]); // Psi_r calculation from rho_rpi or rho_rmi xmm0 = simde_mm256_broadcastw_epi16(_mm_set1_epi16(0)); // ZERO for abs_pi16 @@ -1871,15 +1755,15 @@ void nr_ulsch_qam64_qam64(c16_t *stream0_in, // Rearrange desired MF output simde__m256i y0r, y0i; - separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); + simde_mm256_separate_real_imag_parts(&y0r, &y0i, stream0_256i_in[i], stream0_256i_in[i + 1]); // Rearrange desired channel magnitudes // [|h|^2(1),|h|^2(1),|h|^2(2),|h|^2(2),...,,|h|^2(7),|h|^2(7)]*(2/sqrt(10)) // xmm2 is dummy variable that contains the same values as ch_mag_des - separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); + simde_mm256_separate_real_imag_parts(&ch_mag_des, &xmm2, ch_mag_256i[i], ch_mag_256i[i + 1]); // Rearrange interfering channel magnitudes - separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); + simde_mm256_separate_real_imag_parts(&ch_mag_int, &xmm2, ch_mag_256i_i[i], ch_mag_256i_i[i + 1]); y0r_one_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, ONE_OVER_SQRT_42); y0r_three_over_sqrt_21 = simde_mm256_mulhi_epi16(y0r, THREE_OVER_SQRT_42); diff --git a/openair1/PHY/TOOLS/simde_operations.c b/openair1/PHY/TOOLS/simde_operations.c new file mode 100644 index 0000000000..a61956d87b --- /dev/null +++ b/openair1/PHY/TOOLS/simde_operations.c @@ -0,0 +1,60 @@ +/* + * 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 + */ + +#include + +void simde_mm128_separate_real_imag_parts(__m128i *out_re, __m128i *out_im, __m128i in0, __m128i in1) +{ + // Put in0 = [Re(0,1) Re(2,3) Im(0,1) Im(2,3)] + in0 = simde_mm_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = simde_mm_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = simde_mm_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // Put xmm1 = [Re(4,5) Re(6,7) Im(4,5) Im(6,7)] + in1 = simde_mm_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = simde_mm_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = simde_mm_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + *out_re = simde_mm_unpacklo_epi64(in0, in1); + *out_im = simde_mm_unpackhi_epi64(in0, in1); +} + +void simde_mm256_separate_real_imag_parts(__m256i *out_re, __m256i *out_im, __m256i in0, __m256i in1) +{ + // Put in0 = [Re(0,1,2,3) Im(0,1,2,3) Re(4,5,6,7) Im(4,5,6,7)] + in0 = simde_mm256_shufflelo_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = simde_mm256_shufflehi_epi16(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in0 = simde_mm256_shuffle_epi32(in0, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // Put in1 = [Re(8,9,10,11) Im(8,9,10,11) Re(12,13,14,15) Im(12,13,14,15)] + in1 = simde_mm256_shufflelo_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = simde_mm256_shufflehi_epi16(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + in1 = simde_mm256_shuffle_epi32(in1, 0xd8); //_MM_SHUFFLE(0,2,1,3)); + + // Put tmp0 =[Re(0,1,2,3) Re(8,9,10,11) Re(4,5,6,7) Re(12,13,14,15)] + __m256i tmp0 = simde_mm256_unpacklo_epi64(in0, in1); + + // Put tmp1 = [Im(0,1,2,3) Im(8,9,10,11) Im(4,5,6,7) Im(12,13,14,15)] + __m256i tmp1 = simde_mm256_unpackhi_epi64(in0, in1); + + *out_re = simde_mm256_permute4x64_epi64(tmp0, 0xd8); + *out_im = simde_mm256_permute4x64_epi64(tmp1, 0xd8); +} \ No newline at end of file diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 4076352455..060b85f94e 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -851,6 +851,8 @@ c32_t dot_product(const c16_t *x, double interp(double x, double *xs, double *ys, int count); +void simde_mm128_separate_real_imag_parts(__m128i *out_re, __m128i *out_im, __m128i in0, __m128i in1); +void simde_mm256_separate_real_imag_parts(__m256i *out_re, __m256i *out_im, __m256i in0, __m256i in1); #ifdef __cplusplus } From 70270250e853930560a9494e3b852582f75722a0 Mon Sep 17 00:00:00 2001 From: Roberto Louro Magueta Date: Thu, 27 Apr 2023 19:43:01 +0100 Subject: [PATCH 11/19] Select Nonlinear ML or Linear MMSE receiver --- openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 405a73a5fd..b06b690c0b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1899,9 +1899,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, unsigned char harq_pid) { - // Temporary flag: (true) ML receiver, (false) MMSE receiver - bool ml_rx = true; - uint8_t aarx, aatx; uint32_t nb_re_pusch, bwp_start_subcarrier; int avgs = 0; @@ -2002,6 +1999,15 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, uint32_t rxdataF_ext_offset = 0; uint8_t shift_ch_ext = rel15_ul->nrOfLayers > 1 ? log2_approx(max_ch >> 11) : 0; + // Flag to select the receiver: (true) Nonlinear ML receiver, (false) Linear MMSE receiver + // By default, we are using the Nonlinear ML receiver, except + // - for 256QAM as Nonlinear ML receiver is not implemented for 256QAM + // - for 64QAM as Nonlinear ML receiver requires more processing time than MMSE, and many machines are not powerful enough + bool ml_rx = true; + if (rel15_ul->nrOfLayers != 2 || rel15_ul->qam_mod_order >= 6) { + ml_rx = false; + } + int ad_shift = 0; if (rel15_ul->nrOfLayers == 1) { ad_shift = 1 + log2_approx(frame_parms->nb_antennas_rx >> 2); From 8cf27b0af81ede6473778e94dbab069dc8439fbd Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 27 Jun 2023 14:05:39 +0200 Subject: [PATCH 12/19] chore(ci-cn): starting 2023/06/22, CN5G images do not support anymore env-variable-based deployment configuration * A common YAML file shall be mounted * Currently SPGWU-TINY is still using the old configuration scheme - But a new UPF is soon to be released Signed-off-by: Raphael Defosseux --- doc/tutorial_resources/oai-cn5g/docker-compose.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/tutorial_resources/oai-cn5g/docker-compose.yml b/doc/tutorial_resources/oai-cn5g/docker-compose.yml index b57942fea0..fc9eab0ad5 100644 --- a/doc/tutorial_resources/oai-cn5g/docker-compose.yml +++ b/doc/tutorial_resources/oai-cn5g/docker-compose.yml @@ -36,7 +36,7 @@ services: ipv4_address: 192.168.70.139 oai-udr: container_name: "oai-udr" - image: oaisoftwarealliance/oai-udr:develop + image: oaisoftwarealliance/oai-udr:v1.5.1 environment: - TZ=Europe/Paris - UDR_NAME=OAI_UDR @@ -58,7 +58,7 @@ services: ipv4_address: 192.168.70.136 oai-udm: container_name: "oai-udm" - image: oaisoftwarealliance/oai-udm:develop + image: oaisoftwarealliance/oai-udm:v1.5.1 environment: - TZ=Europe/Paris - UDM_NAME=OAI_UDM @@ -77,7 +77,7 @@ services: ipv4_address: 192.168.70.137 oai-ausf: container_name: "oai-ausf" - image: oaisoftwarealliance/oai-ausf:develop + image: oaisoftwarealliance/oai-ausf:v1.5.1 environment: - TZ=Europe/Paris - AUSF_NAME=OAI_AUSF @@ -96,7 +96,7 @@ services: ipv4_address: 192.168.70.138 oai-nrf: container_name: "oai-nrf" - image: oaisoftwarealliance/oai-nrf:develop + image: oaisoftwarealliance/oai-nrf:v1.5.1 environment: - TZ=Europe/Paris - NRF_INTERFACE_NAME_FOR_SBI=eth0 @@ -105,7 +105,7 @@ services: ipv4_address: 192.168.70.130 oai-amf: container_name: "oai-amf" - image: oaisoftwarealliance/oai-amf:develop + image: oaisoftwarealliance/oai-amf:v1.5.1 environment: - TZ=Europe/Paris # PLMN informations @@ -151,7 +151,7 @@ services: ipv4_address: 192.168.70.132 oai-smf: container_name: "oai-smf" - image: oaisoftwarealliance/oai-smf:develop + image: oaisoftwarealliance/oai-smf:v1.5.1 environment: - TZ=Europe/Paris - SMF_INTERFACE_NAME_FOR_N4=eth0 @@ -202,7 +202,7 @@ services: ipv4_address: 192.168.70.133 oai-spgwu-tiny: container_name: "oai-spgwu-tiny" - image: oaisoftwarealliance/oai-spgwu-tiny:develop + image: oaisoftwarealliance/oai-spgwu-tiny:v1.5.1 environment: - TZ=Europe/Paris - SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP=eth0 From 72927faf06cd7d6f2926a503f17453e22a871665 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 4 Jun 2023 09:43:21 +0200 Subject: [PATCH 13/19] some refactoring in dci configuration --- .../NR_MAC_UE/nr_ue_dci_configuration.c | 141 +++++++++--------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index b3389df86a..8b99818508 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -96,9 +96,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, const NR_SearchSpace_t *ss) { - uint16_t monitoringSymbolsWithinSlot = 0; - int sps = 0; - const NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; const NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP; NR_BWP_Id_t dl_bwp_id = current_DL_BWP ? current_DL_BWP->bwp_id : 0; @@ -187,70 +184,72 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, mac->cg, &mac->def_dci_pdu_rel15[dl_config->slot][dci_format], dci_format, - NR_RNTI_TC, + rnti_type, coreset, dl_bwp_id, ss->searchSpaceType->present, mac->type0_PDCCH_CSS_config.num_rbs, alt_size); - - rel15->BWPStart = coreset_id == 0 ? mac->type0_PDCCH_CSS_config.cset_start_rb : current_DL_BWP->BWPStart; - rel15->BWPSize = coreset_id == 0 ? mac->type0_PDCCH_CSS_config.num_rbs : current_DL_BWP->BWPSize; - - switch(rnti_type) { - case NR_RNTI_C: - // we use DL BWP dedicated - sps = current_DL_BWP->cyclicprefix ? 12 : 14; - // for SPS=14 8 MSBs in positions 13 down to 6 - monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - rel15->rnti = mac->crnti; - rel15->SubcarrierSpacing = current_DL_BWP->scs; - break; - case NR_RNTI_RA: - // we use the initial DL BWP - sps = current_DL_BWP->cyclicprefix == NULL ? 14 : 12; - monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - rel15->rnti = mac->ra.ra_rnti; - rel15->SubcarrierSpacing = current_DL_BWP->scs; - break; - case NR_RNTI_P: - break; - case NR_RNTI_CS: - break; - case NR_RNTI_TC: - // we use the initial DL BWP - sps = current_DL_BWP->cyclicprefix == NULL ? 14 : 12; - monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - rel15->rnti = mac->ra.t_crnti; - rel15->SubcarrierSpacing = current_DL_BWP->scs; - break; - case NR_RNTI_SP_CSI: - break; - case NR_RNTI_SI: - sps=14; - // for SPS=14 8 MSBs in positions 13 down to 6 - monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - - rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values - - rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; - if(mac->frequency_range == FR2) - rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2; - break; - case NR_RNTI_SFI: - break; - case NR_RNTI_INT: - break; - case NR_RNTI_TPC_PUSCH: - break; - case NR_RNTI_TPC_PUCCH: - break; - case NR_RNTI_TPC_SRS: - break; - default: - break; - } } + + rel15->BWPStart = coreset_id == 0 ? mac->type0_PDCCH_CSS_config.cset_start_rb : current_DL_BWP->BWPStart; + rel15->BWPSize = coreset_id == 0 ? mac->type0_PDCCH_CSS_config.num_rbs : current_DL_BWP->BWPSize; + + uint16_t monitoringSymbolsWithinSlot = 0; + int sps = 0; + + switch(rnti_type) { + case NR_RNTI_C: + // we use DL BWP dedicated + sps = current_DL_BWP->cyclicprefix ? 12 : 14; + // for SPS=14 8 MSBs in positions 13 down to 6 + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = mac->crnti; + rel15->SubcarrierSpacing = current_DL_BWP->scs; + break; + case NR_RNTI_RA: + // we use the initial DL BWP + sps = current_DL_BWP->cyclicprefix == NULL ? 14 : 12; + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = mac->ra.ra_rnti; + rel15->SubcarrierSpacing = current_DL_BWP->scs; + break; + case NR_RNTI_P: + break; + case NR_RNTI_CS: + break; + case NR_RNTI_TC: + // we use the initial DL BWP + sps = current_DL_BWP->cyclicprefix == NULL ? 14 : 12; + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = mac->ra.t_crnti; + rel15->SubcarrierSpacing = current_DL_BWP->scs; + break; + case NR_RNTI_SP_CSI: + break; + case NR_RNTI_SI: + sps=14; + // for SPS=14 8 MSBs in positions 13 down to 6 + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values + rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; + if(mac->frequency_range == FR2) + rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon + 2; + break; + case NR_RNTI_SFI: + break; + case NR_RNTI_INT: + break; + case NR_RNTI_TPC_PUSCH: + break; + case NR_RNTI_TPC_PUCCH: + break; + case NR_RNTI_TPC_SRS: + break; + default: + break; + } + for (int i = 0; i < sps; i++) { if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { rel15->coreset.StartSymbolIndex = i; @@ -263,15 +262,17 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fill_dci_search_candidates(ss, rel15, Y); #ifdef DEBUG_DCI - LOG_D(MAC, "[DCI_CONFIG] Configure DCI PDU: rnti_type %d BWPSize %d BWPStart %d rel15->SubcarrierSpacing %d rel15->dci_format %d rel15->dci_length %d sps %d monitoringSymbolsWithinSlot %d \n", - rnti_type, - rel15->BWPSize, - rel15->BWPStart, - rel15->SubcarrierSpacing, - rel15->dci_format_options[0], - rel15->dci_length_options[0], - sps, - monitoringSymbolsWithinSlot); + for (int i = 0; i < rel15->num_dci_options; i++) { + LOG_D(MAC, "[DCI_CONFIG] Configure DCI PDU: rnti_type %d BWPSize %d BWPStart %d rel15->SubcarrierSpacing %d rel15->dci_format %d rel15->dci_length %d sps %d monitoringSymbolsWithinSlot %d \n", + rnti_type, + rel15->BWPSize, + rel15->BWPStart, + rel15->SubcarrierSpacing, + rel15->dci_format_options[i], + rel15->dci_length_options[i], + sps, + monitoringSymbolsWithinSlot); + } #endif // add DCI dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; From 409df4bb982e516602490aac8dca0170ca838f2a Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 4 Jun 2023 09:51:00 +0200 Subject: [PATCH 14/19] remove unnecessary part of dci scehduler for RA --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index b60e0199a2..b1be2a6190 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -951,7 +951,7 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) nr_scheduled_response_t scheduled_response; nr_dcireq_t dcireq; - if(mac->state == UE_CONNECTED) { + if(mac->state > UE_NOT_SYNC) { dcireq.module_id = mod_id; dcireq.gNB_index = gNB_index; @@ -964,8 +964,10 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) if(mac->ul_time_alignment.ta_apply) schedule_ta_command(dl_config, &mac->ul_time_alignment); - nr_schedule_csirs_reception(mac, rx_frame, rx_slot); - nr_schedule_csi_for_im(mac, rx_frame, rx_slot); + if(mac->state == UE_CONNECTED) { + nr_schedule_csirs_reception(mac, rx_frame, rx_slot); + nr_schedule_csi_for_im(mac, rx_frame, rx_slot); + } dcireq.dl_config_req = *dl_config; fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->phy_data); @@ -974,19 +976,6 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) mac->if_module->scheduled_response(&scheduled_response); } } - else if (mac->state == UE_PERFORMING_RA) { - // this is for Msg2/Msg4 - if (mac->ra.ra_state >= WAIT_RAR) { - if(mac->ul_time_alignment.ta_apply) - schedule_ta_command(dl_config, &mac->ul_time_alignment); - config_dci_pdu(mac, dl_config, mac->ra.ra_state == WAIT_RAR ? NR_RNTI_RA : NR_RNTI_TC , rx_slot, mac->ra_SS); - dl_config->number_pdus = 1; - LOG_D(MAC,"mac->cg %p: Calling fill_scheduled_response for type0_pdcch, num_pdus %d\n", mac->cg, dl_config->number_pdus); - fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->phy_data); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); - } - } else dl_config->number_pdus = 0; } From 8c2c89491c50aeb375547e369365273e899a778a Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 6 Jun 2023 12:40:34 +0200 Subject: [PATCH 15/19] fix for not initialized pduBitmap --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 6c8a0f337f..4bd00691df 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -653,6 +653,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti; fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; + dlsch_config_pdu_1_0->pduBitmap = 0; + NR_PDSCH_Config_t *pdsch_config = current_DL_BWP ? current_DL_BWP->pdsch_Config : NULL; if (dci_ind->ss_type == NR_SearchSpace__searchSpaceType_PR_common) { dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs ? mac->type0_PDCCH_CSS_config.num_rbs : current_DL_BWP->initial_BWPSize; From 1da7cada4858ad0bcbbe36dca151512fbc0e8b42 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 7 Jun 2023 19:10:47 +0200 Subject: [PATCH 16/19] solution to L2 failure -> handling switch to 1_0 --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 26 ++++++++++++-------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 4bd00691df..1f1bdd402b 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -443,13 +443,14 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); - int8_t ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15, slot); - if ((ret&1) == 1) return -1; + int ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15, slot); + if ((ret&1) == 1) + return -1; else if (ret == 2) { - dci->dci_format = NR_UL_DCI_FORMAT_0_0; + dci->dci_format = (dci->dci_format == NR_UL_DCI_FORMAT_0_0) ? NR_DL_DCI_FORMAT_1_0 : NR_UL_DCI_FORMAT_0_0; def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][dci->dci_format]; } - int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); + int ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); return ret_proc; } @@ -2849,7 +2850,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *dci_pdu_rel15, int slot) { - + LOG_D(MAC,"nr_extract_dci_info : dci_pdu %lx, size %d, format %d\n", *dci_pdu, dci_size, dci_format); int pos = 0; int fsize = 0; int rnti_type = get_rnti_type(mac, rnti); @@ -2866,7 +2867,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, current_DL_BWP->initial_BWPSize); else N_RB = mac->type0_PDCCH_CSS_config.num_rbs; - LOG_D(MAC,"nr_extract_dci_info : dci_pdu %lx, size %d\n",*dci_pdu,dci_size); + switch(dci_format) { case NR_DL_DCI_FORMAT_1_0: @@ -2916,7 +2917,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, //switch to DCI_0_0 if (dci_pdu_rel15->format_indicator == 0) { dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_UL_DCI_FORMAT_0_0]; - return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); + return 2 + nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); } #ifdef DEBUG_EXTRACT_DCI LOG_D(MAC,"Format indicator %d (%d bits) N_RB_BWP %d => %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,N_RB,dci_size-pos,*dci_pdu); @@ -3107,7 +3108,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, //switch to DCI_0_0 if (dci_pdu_rel15->format_indicator == 0) { dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_UL_DCI_FORMAT_0_0]; - return 2+nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); + return 2 + nr_extract_dci_info(mac, NR_UL_DCI_FORMAT_0_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); } // Freq domain assignment 0-16 bit @@ -3248,8 +3249,13 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, #ifdef DEBUG_EXTRACT_DCI LOG_I(MAC,"Format indicator %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->format_indicator,1,dci_size-pos,*dci_pdu); #endif - if (dci_pdu_rel15->format_indicator == 1) - return 1; // discard dci, format indicator not corresponding to dci_format + + //switch to DCI_1_0 + if (dci_pdu_rel15->format_indicator == 1) { + dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][NR_DL_DCI_FORMAT_1_0]; + return 2 + nr_extract_dci_info(mac, NR_DL_DCI_FORMAT_1_0, dci_size, rnti, ss_type, dci_pdu, dci_pdu_rel15, slot); + } + fsize = dci_pdu_rel15->frequency_domain_assignment.nbits; pos+=fsize; dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1< Date: Tue, 27 Jun 2023 19:20:34 +0200 Subject: [PATCH 17/19] review --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 7 +++---- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 1f1bdd402b..b1e0c17cc8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -443,15 +443,14 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); - int ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15, slot); - if ((ret&1) == 1) + const int ret = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, dci->ss_type, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15, slot); + if ((ret & 1) == 1) return -1; else if (ret == 2) { dci->dci_format = (dci->dci_format == NR_UL_DCI_FORMAT_0_0) ? NR_DL_DCI_FORMAT_1_0 : NR_UL_DCI_FORMAT_0_0; def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[slot][dci->dci_format]; } - int ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); - return ret_proc; + return nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); } int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index b1be2a6190..51c4d6f184 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -951,7 +951,7 @@ void nr_ue_dl_scheduler(nr_downlink_indication_t *dl_info) nr_scheduled_response_t scheduled_response; nr_dcireq_t dcireq; - if(mac->state > UE_NOT_SYNC) { + if(mac->state > UE_NOT_SYNC) { dcireq.module_id = mod_id; dcireq.gNB_index = gNB_index; From e45da1a6fa7e587f3682c8cb55bbd678a32e1585 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 22 Jun 2023 19:18:29 +0200 Subject: [PATCH 18/19] moving handling of RA success for reconfigurationWithSync at RRC --- .../SIMULATION/NR_PHY/nr_dummy_functions.c | 2 ++ openair2/COMMON/mac_messages_def.h | 2 ++ openair2/COMMON/mac_messages_types.h | 10 ++++++++- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- openair2/RRC/NR_UE/L2_interface_ue.c | 12 +++++------ openair2/RRC/NR_UE/rrc_UE.c | 21 +++++++++++++++++++ openair2/RRC/NR_UE/rrc_proto.h | 1 + 7 files changed, 41 insertions(+), 9 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index dccdce2934..6d3948974d 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -32,6 +32,8 @@ void nr_mac_rrc_sync_ind(const module_id_t module_id, const frame_t frame, const bool in_sync) {} +void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success) {} + void rrc_data_ind(const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const sdu_size_t sdu_sizeP, diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h index d4a923b90b..50e7a108c9 100644 --- a/openair2/COMMON/mac_messages_def.h +++ b/openair2/COMMON/mac_messages_def.h @@ -48,6 +48,8 @@ MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDat MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req) +MESSAGE_DEF(NR_RRC_MAC_RA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacRaInd, nr_rrc_mac_ra_ind) + /* RRC configures DRX context (MAC timers) of a UE */ MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req) diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index fde990b0fe..5703a886c0 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -54,7 +54,9 @@ #define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind #define RRC_MAC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req -#define RRC_MAC_DRX_CONFIG_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_drx_config_req +#define NR_RRC_MAC_RA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_ra_ind + +#define RRC_MAC_DRX_CONFIG_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_drx_config_req // Some constants from "LAYER2/MAC/defs.h" #define BCCH_SDU_SIZE (512) @@ -65,6 +67,12 @@ //-------------------------------------------------------------------------------------------// // Messages between RRC and MAC layers + +typedef struct NRRrcMacRaInd_s { + uint32_t frame; + bool RA_succeeded; +} NRRrcMacRaInd; + typedef struct RrcMacInSyncInd_s { uint32_t frame; uint8_t sub_frame; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 130b46143b..1c09ec574d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -896,7 +896,6 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr if (ra->cfra) { LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot); - nr_rrc_RA_succeeded(mod_id, gNB_index); mac->state = UE_CONNECTED; ra->RA_window_cnt = -1; } else { @@ -911,6 +910,7 @@ void nr_ra_succeeded(const module_id_t mod_id, const uint8_t gNB_index, const fr LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id); ra->RA_active = 0; ra->ra_state = RA_SUCCEEDED; + nr_mac_rrc_ra_ind(mod_id, frame, true); } // Handling failure of RA procedure @ MAC layer diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 7222defbe4..06fb26536e 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -155,12 +155,10 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, return 0; } -int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) +void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success) { - if (NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active == true) { - LOG_W(NR_RRC, "T304 was stoped with value %i\n", NR_UE_rrc_inst[mod_id].timers_and_constants.T304_cnt); - NR_UE_rrc_inst[mod_id].timers_and_constants.T304_active = false; - NR_UE_rrc_inst[mod_id].timers_and_constants.T304_cnt = 0; - } - return 0; + MessageDef *message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_RA_IND); + NR_RRC_MAC_RA_IND (message_p).frame = frame; + NR_RRC_MAC_RA_IND (message_p).RA_succeeded = success; + itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(mod_id), message_p); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 69efec94ce..87f7e50157 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2249,6 +2249,18 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, return 0; } +void nr_rrc_handle_ra_indication(unsigned int mod_id, bool ra_succeeded) +{ + NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants; + if (ra_succeeded && timers->T304_active == true) { + // successful Random Access procedure triggered by reconfigurationWithSync + timers->T304_active = false; + timers->T304_cnt = 0; + // TODO handle the rest of procedures as described in 5.3.5.3 for when + // reconfigurationWithSync is included in spCellConfig + } +} + void *rrc_nrue_task(void *args_p) { MessageDef *msg_p; @@ -2293,6 +2305,15 @@ void *rrc_nrue_task(void *args_p) nr_rrc_handle_timers(timers); break; + case NR_RRC_MAC_RA_IND: + LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n RA %s", + ue_mod_id, + ITTI_MSG_NAME (msg_p), + NR_RRC_MAC_RA_IND (msg_p).frame, + NR_RRC_MAC_RA_IND (msg_p).RA_succeeded ? "successful" : "failed"); + nr_rrc_handle_ra_indication(ue_mod_id, NR_RRC_MAC_RA_IND (msg_p).RA_succeeded); + break; + case NR_RRC_MAC_BCCH_DATA_IND: LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index f303d809fe..67369a8488 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -116,6 +116,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, void nr_mac_rrc_sync_ind(const module_id_t module_id, const frame_t frame, const bool in_sync); +void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success); /**\brief \param module_id module id From a0a2248ea1f6c082b1eeb407b9b0aaf46ce3f0a2 Mon Sep 17 00:00:00 2001 From: Melissa Elkadi Date: Fri, 30 Jun 2023 18:53:29 +0200 Subject: [PATCH 19/19] Introduce #defines for Sidelink Synchronization Implement the #define variables required for synchronization: These variables include offset and payload size values that vary from the Uu interface, in relation to the PSS, SSS and PBCH elements. We also introduce the new sl_mode command line flag, which is used to switch between the Uu interface and SL interface. This will allow us to modify exisitng PSS and SSS functions, without copying complete 5G functions and only changing a few lines to support sidelink mode. Fixing formatting for softmodem-common.h --- executables/softmodem-common.h | 16 +++++- .../nrPolar_tools/nr_polar_decoding_tools.c | 14 ++++-- .../CODING/nrPolar_tools/nr_polar_pbch_defs.h | 3 ++ openair1/PHY/NR_REFSIG/ss_pbch_nr.h | 10 ++++ openair1/PHY/NR_REFSIG/sss_nr.h | 9 ++++ openair1/PHY/NR_UE_TRANSPORT/pss_nr.c | 18 ++++--- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 50 ++++++++++--------- openair1/PHY/defs_nr_UE.h | 21 ++++++++ openair1/PHY/defs_nr_common.h | 4 ++ .../NR_UE_PHY/unit_tests/src/pss_test.c | 10 ++-- .../NR_UE_PHY/unit_tests/src/pss_util_test.c | 21 +++++--- .../NR_UE_PHY/unit_tests/src/sss_test.c | 4 +- 12 files changed, 130 insertions(+), 50 deletions(-) diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 1f37c9bdea..097546568f 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -58,7 +58,7 @@ extern "C" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" #define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n" #define CONFIG_HLP_SA "run gNB in standalone mode\n" -#define CONFIG_HLP_SL_MODE "sets the NR sidelink mode (0: not in sidelink mode, 1: in-coverage/gNB, 2: out-of-coverage/no gNB)" +#define CONFIG_HLP_SL_MODE "sets the NR sidelink mode (0: not in sidelink mode, 1: in-coverage/gNB, 2: out-of-coverage/no gNB)\n" #define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n" #define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" #define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" @@ -106,6 +106,9 @@ extern "C" #define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n" #define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n" #define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence" +#define CONFIG_HLP_SYNC_REF "Sync Reference in Sidelink\n" +#define CONFIG_HLP_NID1 "Set NID1 value in Sidelink\n" +#define CONFIG_HLP_NID2 "Set NID2 value in Sidelink\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -137,6 +140,10 @@ extern "C" #define NON_STOP softmodem_params.non_stop #define EMULATE_L1 softmodem_params.emulate_l1 #define CONTINUOUS_TX softmodem_params.continuous_tx +#define SYNC_REF softmodem_params.sync_ref +#define NID1 softmodem_params.nid1 +#define NID2 softmodem_params.nid2 + #define REORDER_THREAD_DISABLE softmodem_params.reorder_thread_disable #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; @@ -181,6 +188,8 @@ extern int usrp_tx_thread; {"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, .iptr=&EMULATE_L1, .defintval=0, TYPE_INT, 0}, \ {"continuous-tx", CONFIG_HLP_CONTINUOUS_TX, PARAMFLAG_BOOL, .iptr=&CONTINUOUS_TX, .defintval=0, TYPE_INT, 0}, \ {"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \ + {"nid1", CONFIG_HLP_NID1, 0, .iptr=&NID1, .defintval=10, TYPE_INT, 0}, \ + {"nid2", CONFIG_HLP_NID2, 0, .iptr=&NID2, .defintval=1, TYPE_INT, 0}, \ } // clang-format on @@ -227,6 +236,8 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } // clang-format on @@ -335,6 +346,9 @@ typedef struct { int non_stop; int emulate_l1; int continuous_tx; + int sync_ref; + int nid1; + int nid2; } softmodem_params_t; extern uint64_t get_softmodem_optmask(void); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c index 20ecc690b3..7fd8d351ff 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -351,9 +351,17 @@ void applyGtoright(const t_nrPolar_params *pp,decoder_node_t *node) { ((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__m64 *)alpha_v)[0],((__m64 *)betal)[0])); } else - {// equivalent scalar code to above, activated only on non x86/ARM architectures or Nv=1,2 - for (int i=0;iNv/2;i++) { - alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]); + { + int temp_alpha_r; + for (int i = 0; i < node->Nv / 2; i++) { + temp_alpha_r = alpha_v[i + (node->Nv / 2)] - (betal[i] * alpha_v[i]); + if (temp_alpha_r > SHRT_MAX) { + alpha_r[i] = SHRT_MAX; + } else if (temp_alpha_r < -SHRT_MAX) { + alpha_r[i] = -SHRT_MAX; + } else { + alpha_r[i] = temp_alpha_r; + } } } if (node->Nv == 2) { // apply hard decision on right node diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h index 2ced9633ce..1904d1bd83 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h @@ -35,6 +35,7 @@ #define NR_POLAR_PBCH_AGGREGATION_LEVEL 0 //uint8_t #define NR_POLAR_PBCH_MESSAGE_TYPE 0 //int8_t +#define NR_POLAR_PSBCH_MESSAGE_TYPE 3 //int8_t #define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t #define NR_POLAR_PBCH_CRC_PARITY_BITS 24 #define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3 @@ -52,6 +53,8 @@ #define NR_POLAR_PBCH_I_BIL 0 //uint8_t #define NR_POLAR_PBCH_E 864 //uint16_t #define NR_POLAR_PBCH_E_DWORD 27 // NR_POLAR_PBCH_E/32 +#define NR_POLAR_PSBCH_E 1792 //uint16_t +#define NR_POLAR_PSBCH_E_DWORD 56 // NR_POLAR_PSBCH_E/32 /* * TEST CODE diff --git a/openair1/PHY/NR_REFSIG/ss_pbch_nr.h b/openair1/PHY/NR_REFSIG/ss_pbch_nr.h index ad96054c12..0929d483cd 100644 --- a/openair1/PHY/NR_REFSIG/ss_pbch_nr.h +++ b/openair1/PHY/NR_REFSIG/ss_pbch_nr.h @@ -41,6 +41,9 @@ /* PSS parameters */ #define NUMBER_PSS_SEQUENCE (3) +#define NUMBER_PSS_SEQUENCE_SL (2) +#define PSS_SSS_SUB_CARRIER_START (56) +#define PSS_SSS_SUB_CARRIER_START_SL (2) #define INVALID_PSS_SEQUENCE (NUMBER_PSS_SEQUENCE) #define LENGTH_PSS_NR (127) #define N_SC_RB (12) /* Resource block size in frequency domain expressed as a number if subcarriers */ @@ -62,6 +65,13 @@ #define SSS_SYMBOL_NB ((2) + OFFSET_SS_PBCH) #define PBCH_LAST_SYMBOL_NB ((3) + OFFSET_SS_PBCH) + +#define OFFSET_SS_PSBCH -1 +#define PSS0_SL_SYMBOL_NB ((1) + OFFSET_SS_PSBCH) +#define PSS1_SL_SYMBOL_NB ((2) + OFFSET_SS_PSBCH) +#define SSS0_SL_SYMBOL_NB ((3) + OFFSET_SS_PSBCH) +#define SSS1_SL_SYMBOL_NB ((4) + OFFSET_SS_PSBCH) + /* SS/PBCH parameters */ #define N_RB_SS_PBCH_BLOCK (20) #define NB_SYMBOLS_PBCH (3) diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 7303d99d3b..38d6e72819 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -47,13 +47,22 @@ #define SCALING_METRIC_SSS_NR (15)//(19) #define N_ID_2_NUMBER (NUMBER_PSS_SEQUENCE) +#define N_ID_2_NUMBER_SL (NUMBER_PSS_SEQUENCE_SL) #define N_ID_1_NUMBER (NUMBER_SSS_SEQUENCE) #define GET_NID2(Nid_cell) (Nid_cell%3) #define GET_NID1(Nid_cell) (Nid_cell/3) +#define GET_NID2_SL(Nid_SL) (Nid_SL/NUMBER_SSS_SEQUENCE) +#define GET_NID1_SL(Nid_SL) (Nid_SL%NUMBER_SSS_SEQUENCE) + #define PSS_SC_START_NR (52) /* see from TS 38.211 table 7.4.3.1-1: Resources within an SS/PBCH block for PSS... */ +#define SSS_START_IDX (3) /* [0:PSBCH 1:PSS0 2:PSS1 3:SSS0 4:SSS1] */ +#define NUM_SSS_SYMBOLS (2) + +#define SSS_METRIC_FLOOR_NR (30000) + /************** VARIABLES *****************************************/ #define PHASE_HYPOTHESIS_NUMBER (16) diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index 48486bbdee..7323d27dbb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -73,7 +73,7 @@ int16_t *get_primary_synchro_nr2(const int nid2) * *********************************************************************/ -void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) +void generate_pss_nr(NR_DL_FRAME_PARMS *fp, int N_ID_2) { AssertFatal(fp->ofdm_symbol_size > 127,"Illegal ofdm_symbol_size %d\n",fp->ofdm_symbol_size); AssertFatal(N_ID_2>=0 && N_ID_2 <=2,"Illegal N_ID_2 %d\n",N_ID_2); @@ -88,9 +88,8 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) assert(N_ID_2 < NUMBER_PSS_SEQUENCE); memcpy(x, x_initial, sizeof(x_initial)); - for (int i=0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++) { - x[i+INITIAL_PSS_NR] = (x[i + 4] + x[i])%(2); - } + for (int i = 0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++) + x[i + INITIAL_PSS_NR] = (x[i + 4] + x[i]) % (2); for (int n=0; n < LENGTH_PSS_NR; n++) { const int m = (n + 43 * N_ID_2) % (LENGTH_PSS_NR); @@ -139,7 +138,8 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) * sample 0 is for continuous frequency which is used here */ - unsigned int k = fp->first_carrier_offset + fp->ssb_start_subcarrier + 56; //and + unsigned int subcarrier_start = get_softmodem_params()->sl_mode == 0 ? PSS_SSS_SUB_CARRIER_START : PSS_SSS_SUB_CARRIER_START_SL; + unsigned int k = fp->first_carrier_offset + fp->ssb_start_subcarrier + subcarrier_start; if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size; c16_t synchroF_tmp[fp->ofdm_symbol_size] __attribute__((aligned(32))); memset(synchroF_tmp, 0, sizeof(synchroF_tmp)); @@ -237,7 +237,8 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) static void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue) { AssertFatal(frame_parms_ue->ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n", frame_parms_ue->ofdm_symbol_size); - for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) { + int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; + for (int i = 0; i < pss_sequence; i++) { primary_synchro_nr2[i] = malloc16_clear(LENGTH_PSS_NR * sizeof(int16_t)); AssertFatal(primary_synchro_nr2[i], "Fatal memory allocation problem \n"); primary_synchro_time_nr[i] = malloc16_clear(frame_parms_ue->ofdm_symbol_size * sizeof(c16_t)); @@ -583,7 +584,8 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i pss_source = 0; int maxval=0; - for (int j = 0; j < NUMBER_PSS_SEQUENCE; j++) + int max_size = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; + for (int j = 0; j < max_size; j++) for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { maxval = max(maxval, abs(primary_synchro_time_nr[j][i].r)); maxval = max(maxval, abs(primary_synchro_time_nr[j][i].i)); @@ -595,7 +597,7 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i /* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */ uint16_t pss_index_start = 0; - uint16_t pss_index_end = NUMBER_PSS_SEQUENCE; + uint16_t pss_index_end = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; if (ue->target_Nid_cell != -1) { pss_index_start = GET_NID2(ue->target_Nid_cell); pss_index_end = pss_index_start + 1; diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 2f53a7b95d..cb8e4f40e9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -36,7 +36,7 @@ #include "PHY/defs_nr_UE.h" #include "PHY/MODULATION/modulation_UE.h" - +#include "executables/softmodem-common.h" #include "PHY/NR_REFSIG/ss_pbch_nr.h" #define DEFINE_VARIABLES_SSS_NR_H @@ -78,31 +78,25 @@ void init_context_sss_nr(int amp) int16_t x1[LENGTH_SSS_NR]; int16_t dss_current; int m0, m1; + int nid_2_num = get_softmodem_params()->sl_mode == 0 ? N_ID_2_NUMBER : N_ID_2_NUMBER_SL; const int x0_initial[INITIAL_SSS_NR] = { 1, 0, 0, 0, 0, 0, 0 }; const int x1_initial[INITIAL_SSS_NR] = { 1, 0, 0, 0, 0, 0, 0 }; - - for (int i=0; i < INITIAL_SSS_NR; i++) { + for (int i = 0; i < INITIAL_SSS_NR; i++) { x0[i] = x0_initial[i]; x1[i] = x1_initial[i]; } - - for (int i=0; i < (LENGTH_SSS_NR - INITIAL_SSS_NR); i++) { - x0[i+7] = (x0[i + 4] + x0[i])%(2); - x1[i+7] = (x1[i + 1] + x1[i])%(2); + for (int i = 0; i < (LENGTH_SSS_NR - INITIAL_SSS_NR); i++) { + x0[i + 7] = (x0[i + 4] + x0[i]) % (2); + x1[i + 7] = (x1[i + 1] + x1[i]) % (2); } - for (int N_ID_2 = 0; N_ID_2 < N_ID_2_NUMBER; N_ID_2++) { - + for (int N_ID_2 = 0; N_ID_2 < nid_2_num; N_ID_2++) { for (int N_ID_1 = 0; N_ID_1 < N_ID_1_NUMBER; N_ID_1++) { - - m0 = 15*(N_ID_1/112) + (5*N_ID_2); - m1 = N_ID_1%112; - + m0 = 15 * (N_ID_1 / 112) + (5 * N_ID_2); + m1 = N_ID_1 % 112; for (int n = 0; n < LENGTH_SSS_NR; n++) { - - dss_current = (1 - 2*x0[(n + m0)%(LENGTH_SSS_NR)])*(1 - 2*x1[(n + m1)%(LENGTH_SSS_NR)]); - + dss_current = (1 - 2 * x0 [(n + m0) % (LENGTH_SSS_NR)]) * (1 - 2 * x1[(n + m1) % (LENGTH_SSS_NR)]); /* Modulation of SSS is a BPSK TS 36.211 chapter 5.1.2 BPSK */ #if 1 d_sss[N_ID_2][N_ID_1][n] = dss_current;// * amp; @@ -276,8 +270,9 @@ static int do_pss_sss_extract_nr( for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { int pss_symbol = 0; - int sss_symbol = SSS_SYMBOL_NB - PSS_SYMBOL_NB; - + int sss_symbol = get_softmodem_params()->sl_mode == 0 ? + (SSS_SYMBOL_NB - PSS_SYMBOL_NB) : + (SSS0_SL_SYMBOL_NB - PSS0_SL_SYMBOL_NB) ; unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; c16_t *pss_rxF = rxdataF[aarx] + pss_symbol * ofdm_symbol_size; @@ -286,12 +281,16 @@ static int do_pss_sss_extract_nr( c16_t *pss_rxF_ext = pss_ext[aarx]; c16_t *sss_rxF_ext = sss_ext[aarx]; - unsigned int k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + 56; + unsigned int k = frame_parms->first_carrier_offset + + frame_parms->ssb_start_subcarrier + + ((get_softmodem_params()->sl_mode == 0) ? + PSS_SSS_SUB_CARRIER_START : + PSS_SSS_SUB_CARRIER_START_SL); if (k>= frame_parms->ofdm_symbol_size) k-=frame_parms->ofdm_symbol_size; for (int i=0; i < LENGTH_PSS_NR; i++) { - if (doPss) { + if (doPss) { pss_rxF_ext[i] = pss_rxF[k]; } @@ -300,9 +299,7 @@ static int do_pss_sss_extract_nr( } k++; - - if (k == ofdm_symbol_size) k=0; - + if (k == frame_parms->ofdm_symbol_size) k = 0; } } @@ -365,7 +362,12 @@ static int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, * *********************************************************************/ -int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +int rx_sss_nr(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + int32_t *tot_metric, + uint8_t *phase_max, + int *freq_offset_sss, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { uint8_t i; c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR]; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 870f093c74..d4c5a2da49 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -318,6 +318,22 @@ typedef struct { fapi_nr_dl_config_dci_dl_pdu_rel15_t pdcch_config[FAPI_NR_MAX_SS]; } NR_UE_PDCCH_CONFIG; +#define NR_PSBCH_MAX_NB_CARRIERS 132 +#define NR_PSBCH_MAX_NB_MOD_SYMBOLS 99 +#define NR_PSBCH_DMRS_LENGTH 297 // in mod symbols +#define NR_PSBCH_DMRS_LENGTH_DWORD 20 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32) + +/* NR Sidelink PSBCH payload fields + TODO: This will be removed in the future and + filled in by the upper layers once developed. */ +typedef struct { + uint32_t coverageIndicator : 1; + uint32_t tddConfig : 12; + uint32_t DFN : 10; + uint32_t slotIndex : 7; + uint32_t reserved : 2; +} PSBCH_payload; + #define PBCH_A 24 typedef struct { @@ -378,8 +394,12 @@ typedef struct { int if_freq_off; /// \brief Indicator that UE is synchronized to a gNB int is_synchronized; + /// \brief Indicator that UE is synchronized to a SyncRef UE on Sidelink + int is_synchronized_sl; /// \brief Target gNB Nid_cell when UE is resynchronizing int target_Nid_cell; + /// \brief Indicator that UE is an SynchRef UE + int sync_ref; /// Data structure for UE process scheduling UE_nr_proc_t proc; /// Flag to indicate the UE shouldn't do timing correction at all @@ -660,6 +680,7 @@ typedef struct nr_rxtx_thread_data_s { UE_nr_rxtx_proc_t proc; PHY_VARS_NR_UE *UE; int writeBlockSize; + notifiedFIFO_t txFifo; nr_phy_data_t phy_data; int tx_wait_for_dlsch; } nr_rxtx_thread_data_t; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index e8dba45f2b..2b0a07fda7 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -169,6 +169,8 @@ struct NR_DL_FRAME_PARMS { /// Frame type (0 FDD, 1 TDD) frame_type_t frame_type; uint8_t tdd_config; + /// Sidelink Cell ID + uint16_t Nid_SL; /// Cell ID uint16_t Nid_cell; /// subcarrier spacing (15,30,60,120) @@ -260,6 +262,8 @@ struct NR_DL_FRAME_PARMS { uint8_t ssb_index; /// OFDM symbol offset divisor for UL uint32_t ofdm_offset_divisor; + uint16_t tdd_slot_config; + uint8_t tdd_period; }; // PRS config structures diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c index de1249457f..c9e76846e9 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_test.c @@ -119,14 +119,15 @@ void test_synchro_pss_nr(PHY_VARS_NR_UE *PHY_VARS_NR_UE, int position_symbol, in /* search pss */ synchro_position = pss_synchro_nr(PHY_VARS_NR_UE, rate_change); + int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; - if (pss_sequence_number < NUMBER_PSS_SEQUENCE) { + if (pss_sequence_number < pss_sequence) { NID2_value = pss_sequence_number; } else { - NID2_value = NUMBER_PSS_SEQUENCE; + NID2_value = pss_sequence; } - if (NID2_value < NUMBER_PSS_SEQUENCE) { + if (NID2_value < pss_sequence) { test->number_of_tests++; /* position should be adjusted with i&q samples which are successively stored as int16 in the received buffer */ int test_margin = PSS_DETECTION_MARGIN_MAX; /* warning correlation results give an offset position between 0 and 12 */ @@ -213,9 +214,10 @@ int main(int argc, char *argv[]) test_synchro_pss_nr(PHY_vars_UE, 0, INVALID_PSS_SEQUENCE, &test); #endif + int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; for (int index_position = 0; index_position < size_test_position; index_position++) { - for (int number_pss_sequence = 0; number_pss_sequence < NUMBER_PSS_SEQUENCE; number_pss_sequence++) { + for (int number_pss_sequence = 0; number_pss_sequence < pss_sequence; number_pss_sequence++) { p_test_synchro_pss(PHY_vars_UE, test_position[index_position], number_pss_sequence, &test); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c index 9c96d39534..815c12a6a6 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c @@ -111,12 +111,15 @@ void phase_shift_samples(int16_t *samples, int length, int16_t phase_shift_re, i void display_data(int pss_sequence_number, int16_t *rxdata, int position) { #ifdef DEBUG_TEST_PSS - int16_t *pss_sequence[NUMBER_PSS_SEQUENCE] = {primary_synch0_time, primary_synch1_time, primary_synch2_time}; - int16_t *pss_sequence_time = pss_sequence[pss_sequence_number]; + int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; + int16_t *pss_sequence[pss_sequence] = {primary_synch0_time, primary_synch1_time, primary_synch2_time}; + int16_t *pss_sequence_sl[pss_sequence] = {primary_synch0_time, primary_synch1_time}; + int16_t *pss_sequence_time = pss_sequence[pss_sequence_number];; + if (get_softmodem_params()->sl_mode != 0) { + pss_sequence_time = pss_sequence_sl[pss_sequence_number]; printf(" pss %6d data \n", pss_sequence_number); - for (int i = 0; i < 4; i++) { - if (pss_sequence_number < NUMBER_PSS_SEQUENCE) { + if (pss_sequence_number < pss_sequence) { printf("[i %6d] : %4d [i %6d] : %8i at address : %p \n", i, pss_sequence_time[2*i], (i + position), rxdata[2*i + (position*2)], &(rxdata[2*i + (position*2)])); printf("[q %6d] : %4d [q %6d] : %8i at address : %p \n", i, pss_sequence_time[2*i+1], (i + position), rxdata[2*i + 1 + (position*2)], &(rxdata[2*i + 1 + (position*2)])); } else { @@ -242,7 +245,8 @@ int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission int n_ssb_crb = 0; int ssb_subcarrier_offset = 0; nr_init_frame_parms_ue(frame_parms, mu, extended_prefix_flag, N_RB_DL, n_ssb_crb, ssb_subcarrier_offset); - PHY_vars_UE->frame_parms.Nid_cell = (3 * N_ID_1_NUMBER) + N_ID_2_NUMBER; /* set to unvalid value */ + int nid_2_num = get_softmodem_params()->sl_mode == 0 ? N_ID_2_NUMBER : N_ID_2_NUMBER_SL; + PHY_vars_UE->frame_parms.Nid_cell = (3 * N_ID_1_NUMBER) + nid_2_num; /* set to unvalid value */ //phy_init_nr_top(frame_parms); @@ -447,8 +451,8 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p printf("This pss sequence can not be fully written in the received window \n"); return (-1); } - - if ((pss_sequence_number >= NUMBER_PSS_SEQUENCE) && (pss_sequence_number < 0)) { + int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; + if ((pss_sequence_number >= pss_sequence) && (pss_sequence_number < 0)) { printf("Unknow pss sequence %d \n", pss_sequence_number); return (-1); } @@ -504,8 +508,9 @@ void set_sequence_pss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_ if (position_symbol < 0) { set_pss_in_rx_buffer_from_external_buffer(PHY_vars_UE, input_buffer); } + int pss_sequence = get_softmodem_params()->sl_mode == 0 ? NUMBER_PSS_SEQUENCE : NUMBER_PSS_SEQUENCE_SL; /* write pss sequence in received ue buffer */ - else if (pss_sequence_number < NUMBER_PSS_SEQUENCE) { + else if (pss_sequence_number < pss_sequence) { if (position_symbol > (samples_for_frame - frame_parms->ofdm_symbol_size)) { printf("This position for pss sequence %d is not supported because it exceeds the frame length %d!\n", position_symbol, samples_for_frame); exit(0); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c index 6f6594861a..fa2a8cffd1 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c @@ -227,10 +227,10 @@ int main(int argc, char *argv[]) Nid2 = GET_NID2(Nid_cell[index]); Nid1 = GET_NID1(Nid_cell[index]); - + int nid_2_num = get_softmodem_params()->sl_mode == 0 ? N_ID_2_NUMBER : N_ID_2_NUMBER_SL; for (int position = 0; position < size_test_position; position++) { - PHY_vars_UE->frame_parms.Nid_cell = (3 * N_ID_1_NUMBER) + N_ID_2_NUMBER; /* set to invalid value */ + PHY_vars_UE->frame_parms.Nid_cell = (3 * N_ID_1_NUMBER) + nid_2_num; /* set to invalid value */ phase = (*p_test_synchro_pss_sss)(PHY_vars_UE, test_position[position], &frame_parms_gNB, &test); /* return phase index which gives phase error from an array */