Added virtual resource mapping and physical resource mapping

This commit is contained in:
Ejaz Ahmed
2023-03-09 13:34:06 -08:00
parent 854d7481f8
commit dac16c84b8
8 changed files with 283 additions and 300 deletions

View File

@@ -288,6 +288,24 @@ int get_dmrs_port(int nl, uint16_t dmrs_ports) {
return p;
}
int get_dmrs_port_sl(int nl, uint16_t dmrs_ports) {
if (dmrs_ports == 0) return 0; // dci 1_0
int p = -1;
int found = -1;
for (int i = 0; i < 2; i++) { // loop over dmrs ports
if((dmrs_ports >> i) & 0x01) { // check if current bit is 1
found++;
if (found == nl) { // found antenna port number corresponding to current layer
p = i;
break;
}
}
}
AssertFatal(p > -1, "No dmrs port corresponding to layer %d found\n", nl);
return p;
}
frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
{
frame_type_t current_type;

View File

@@ -78,6 +78,7 @@ int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart);
int get_subband_size(int NPRB,int size);
void SLIV2SL(int SLIV,int *S,int *L);
int get_dmrs_port(int nl, uint16_t dmrs_ports);
int get_dmrs_port_sl(int nl, uint16_t dmrs_ports);
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
int get_nb_periods_per_frame(uint8_t tdd_period);
int get_supported_band_index(int scs, int band, int n_rbs);

View File

@@ -0,0 +1,71 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_sch_dmrs.c
* \brief
* \author
* \date
* \version
* \company Eurecom
* \email:
* \note
* \warning
*/
#include "nr_sch_dmrs_sl.h"
/*Table 8.4.1.1.2-2 38211 Columns: ap - CDM group - Delta - Wf(0) - Wf(1) - Wt(0)*/
int8_t pssch_dmrs[2][6] = {{1000, 0, 0, 1, 1, 1},
{1001, 0, 0, 1, -1, 1}};
void get_antenna_ports_sl(uint8_t *ap, uint8_t n_symbs) {
for (int i = 0; i < 2; i++)
*(ap + i) = 1000 + i;
}
void get_Wt_sl(int8_t *Wt, uint8_t ap) {
*(Wt) = pssch_dmrs[ap][5];
}
void get_Wf_sl(int8_t *Wf, uint8_t ap) {
for (int i = 0; i < 2; i++)
*(Wf + i) = pssch_dmrs[ap][3 + i];
}
uint8_t get_delta_sl(uint8_t ap) {
return pssch_dmrs[ap][2];
}
uint16_t get_dmrs_freq_idx_sl(uint16_t n, uint8_t k_prime, uint8_t delta) {
uint16_t dmrs_idx = 6 * n + k_prime + delta;
return dmrs_idx;
}
uint8_t get_l0(uint16_t dlDmrsSymbPos) {
uint16_t mask=dlDmrsSymbPos;
int l0;
for (l0=0;l0<14;l0++) {
if ((mask&1) == 1) break;
mask>>=1;
}
return (l0);
}

View File

@@ -0,0 +1,51 @@
/*
* 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.
*-------------------------------------------------------------------------------
*/
/*! \file PHY/NR_TRANSPORT/nr_sch_dmrs_sl.h
* \brief
* \author
* \date
* \version
* \company
* \email:
* \note
* \warning
*/
#ifndef NR_SCH_DMRS_SL_H
#define NR_SCH_DMRS_SL_H
#include "PHY/defs_nr_common.h"
#define NR_PSSCH_DMRS_ANTENNA_PORT0 1000
#define NR_PSSCH_DMRS_NB_ANTENNA_PORTS 2
void get_antenna_ports_sl(uint8_t *ap, uint8_t n_symbs);
void get_Wt_sl(int8_t *Wt, uint8_t ap);
void get_Wf_sl(int8_t *Wf, uint8_t ap);
uint8_t get_delta_sl(uint8_t ap);
uint16_t get_dmrs_freq_idx_sl(uint16_t n, uint8_t k_prime, uint8_t delta);
uint8_t get_l0(uint16_t dlDmrsSymbPos);
#endif

View File

@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
/*! \file PHY/NR_UE_TRANSPORT/nr_ulsch.c
/*! \file PHY/NR_UE_TRANSPORT/nr_slsch.c
* \brief Top-level routines for transmission of the PUSCH TS 38.211 v 15.4.0
* \author Khalid Ahmed
* \date 2019
@@ -42,6 +42,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
#include "PHY/NR_UE_TRANSPORT/nr_sch_dmrs_sl.h"
#include "PHY/defs_nr_common.h"
#include "PHY/TOOLS/tools_defs.h"
#include "executables/nr-softmodem.h"
@@ -121,26 +122,22 @@ void nr_ue_slsch_tx_procedures(PHY_VARS_NR_UE *UE,
uint8_t thread_id,
int gNB_id) {
LOG_D(PHY,"nr_ue_slsch_tx_procedures hard_id %d %d.%d\n",harq_pid,frame,slot);
LOG_D(NR_PHY, "nr_ue_slsch_tx_procedures hard_id %d %d.%d\n", harq_pid, frame, slot);
int8_t Wf[2], Wt[2];
int l_prime[2], delta;
uint8_t nb_dmrs_re_per_rb;
int i;
int sample_offsetF, N_RE_prime;
int sample_offsetF;
NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms;
int32_t **txdataF = UE->common_vars.txdataF;
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
uint16_t number_dmrs_symbols = 0;
NR_UE_ULSCH_t *ulsch_ue = UE->ulsch[thread_id][gNB_id];//TODO delete it
NR_UE_ULSCH_t *slsch_ue = UE->slsch[thread_id][gNB_id];
NR_UL_UE_HARQ_t *harq_process_ul_ue = slsch_ue->harq_processes[harq_pid];
nfapi_nr_ue_pssch_pdu_t *pssch_pdu = &harq_process_ul_ue->pssch_pdu;
int start_symbol = pssch_pdu->start_symbol_index;
uint16_t sl_dmrs_symb_pos = pssch_pdu->sl_dmrs_symb_pos;
uint8_t number_of_symbols = pssch_pdu->nr_of_symbols;
uint8_t dmrs_type = pssch_pdu->dmrs_config_type;
@@ -150,36 +147,36 @@ void nr_ue_slsch_tx_procedures(PHY_VARS_NR_UE *UE,
uint8_t mod_order = pssch_pdu->qam_mod_order;
uint16_t rnti = pssch_pdu->rnti;
uint8_t cdm_grps_no_data = pssch_pdu->num_dmrs_cdm_grps_no_data;
uint16_t start_sc = frame_parms->first_carrier_offset + (start_rb+pssch_pdu->bwp_start)*NR_NB_SC_PER_RB;
uint16_t bwp_start = pssch_pdu->bwp_start;
int start_symbol = pssch_pdu->start_symbol_index;
frame_parms->first_carrier_offset = 0;
frame_parms->ofdm_symbol_size = 2048;
uint16_t start_sc = frame_parms->first_carrier_offset + (start_rb + bwp_start) * NR_NB_SC_PER_RB;
if (start_sc >= frame_parms->ofdm_symbol_size)
start_sc -= frame_parms->ofdm_symbol_size;
slsch_ue->Nid_cell = frame_parms->Nid_cell;
for (int i = start_symbol; i < start_symbol + number_of_symbols; i++) {
for (int i = start_symbol; i < number_of_symbols; i++) {
if((sl_dmrs_symb_pos >> i) & 0x01)
number_dmrs_symbols += 1;
}
nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data;
LOG_D(PHY,"ulsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n",
rnti,start_rb,nb_rb,mod_order,Nl,pssch_pdu->Tpmi,pssch_pdu->bwp_start,start_sc,start_symbol,number_of_symbols,cdm_grps_no_data,number_dmrs_symbols,nb_dmrs_re_per_rb);
// TbD num_of_mod_symbols is set but never used
N_RE_prime = NR_NB_SC_PER_RB*number_of_symbols - nb_dmrs_re_per_rb*number_dmrs_symbols - N_PRB_oh;
harq_process_ul_ue->num_of_mod_symbols = N_RE_prime*nb_rb;
nb_dmrs_re_per_rb = 6 * cdm_grps_no_data;
LOG_D(NR_PHY, "slsch TX %x : start_rb %d nb_rb %d mod_order %d Nl %d Tpmi %d bwp_start %d start_sc %d start_symbol %d num_symbols %d cdmgrpsnodata %d num_dmrs %d dmrs_re_per_rb %d\n",
rnti, start_rb, nb_rb, mod_order, Nl, pssch_pdu->Tpmi, bwp_start, start_sc, start_symbol, number_of_symbols, cdm_grps_no_data, number_dmrs_symbols, nb_dmrs_re_per_rb);
/////////////////////////SLSCH SCI2 coding/////////////////////////
// TODO: update the following
/* payload is 56 bits */
PSSCH_SCI2_payload pssch_payload; // NR Side Link Payload for Rel 16
pssch_payload.coverageIndicator = 0; // 1 bit
pssch_payload.tddConfig = 0xFFF; // 12 bits for TDD configuration
pssch_payload.DFN = 0x3FF; // 10 bits for DFN
pssch_payload.slotIndex = 0x2A; // 7 bits for Slot Index //frame_parms->p_TDD_UL_DL_ConfigDedicated->slotIndex;
pssch_payload.reserved = 0; // 2 bits reserved
pssch_payload.harq_pid = 4;
pssch_payload.ndi = 0;
pssch_payload.red_version = 0;
pssch_payload.s_id = 0;
pssch_payload.d_id = 0;
pssch_payload.harq_fdbk_enabled = 0;
pssch_payload.ctype_ind = 0;
pssch_payload.csi_request = 0;
NR_UE_PSSCH m_pssch;
UE->pssch_vars[0] = &m_pssch;
@@ -234,7 +231,7 @@ void nr_ue_slsch_tx_procedures(PHY_VARS_NR_UE *UE,
multiplexed_output);
/////////////////////////SLSCH scrambling/////////////////////////
uint32_t scrambled_output[(available_bits >> 5) + 1];
memset(scrambled_output, 0, ((available_bits >> 5) + 1)*sizeof(uint32_t));
memset(scrambled_output, 0, ((available_bits >> 5) + 1) * sizeof(uint32_t));
nr_pusch_codeword_scrambling_sl(multiplexed_output,
available_bits,
@@ -267,37 +264,12 @@ void nr_ue_slsch_tx_procedures(PHY_VARS_NR_UE *UE,
nr_init_pssch_dmrs(UE, Nidx);
uint32_t **pssch_dmrs = UE->nr_gold_pssch_dmrs[slot];
uint16_t n_dmrs = (pssch_pdu->bwp_start + start_rb + nb_rb) * ((dmrs_type == pusch_dmrs_type1) ? 6 : 4);
uint32_t *pssch_dmrs = UE->nr_gold_pssch_dmrs[slot];
uint16_t n_dmrs = (bwp_start + start_rb + nb_rb) * ((dmrs_type == pusch_dmrs_type1) ? 6 : 4);
int16_t mod_dmrs[n_dmrs << 1] __attribute((aligned(16)));
////////////////////////////////////////////////////////////////////////
/////////////////////////PTRS parameters' initialization/////////////////////////
int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
uint8_t L_ptrs, K_ptrs = 0;
uint16_t beta_ptrs = 1; // temp value until power control is implemented
if (pssch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
K_ptrs = harq_process_ul_ue->pssch_pdu.pssch_ptrs.ptrs_freq_density;
L_ptrs = 1<<harq_process_ul_ue->pssch_pdu.pssch_ptrs.ptrs_time_density;
beta_ptrs = 1; // temp value until power control is implemented
slsch_ue->ptrs_symbols = 0;
set_ptrs_symb_idx(&slsch_ue->ptrs_symbols,
number_of_symbols,
start_symbol,
L_ptrs,
sl_dmrs_symb_pos);
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////////SLSCH layer mapping/////////////////////////
int16_t **tx_layers = (int16_t **)malloc16_clear(Nl * sizeof(int16_t *));
@@ -309,305 +281,172 @@ void nr_ue_slsch_tx_procedures(PHY_VARS_NR_UE *UE,
////////////////////////////////////////////////////////////////////////
//////////////////////// SLSCH transform precoding ////////////////////////
////////////////SLSCH Mapping to virtual resource blocks////////////////
l_prime[0] = 0; // single symbol ap 0
pssch_pdu->dmrs_ports = (Nl == 2) ? 0b11 : 0b01;
uint16_t G_SCI2_bits = 1024; // TODO: Update value
uint16_t M_SCI2_Layer = G_SCI2_bits / SCI2_mod_order;
uint16_t index;
uint8_t u = 0, v = 0;
int16_t *dmrs_seq = NULL;
int encoded_length = frame_parms->N_RB_UL * 14 * NR_NB_SC_PER_RB * mod_order * Nl;
int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl * sizeof(int16_t *));
for (int nl = 0; nl < Nl; nl++)
tx_precoding[nl] = (int16_t *)malloc16_clear((encoded_length << 1) * sizeof(int16_t));
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
int32_t y[max_num_re] __attribute__ ((aligned(16)));
if (pssch_pdu->transform_precoding == transformPrecoder_enabled) {
uint32_t nb_re_pssch=nb_rb * NR_NB_SC_PER_RB;
uint32_t y_offset = 0;
uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2);
// Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol
index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol);
u = pssch_pdu->dfts_ofdm.low_papr_group_number;
v = pssch_pdu->dfts_ofdm.low_papr_sequence_number;
dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index];
AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n");
AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated");
LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index);
for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) {
if((sl_dmrs_symb_pos >> l) & 0x01)
/* In the symbol with DMRS no data would be transmitted CDM groups is 2*/
continue;
nr_dft(&y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pssch);
y_offset = y_offset + nb_re_pssch;
LOG_D(NR_PHY, "Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n",
l, nb_re_pssch, y_offset);
#ifdef DEBUG_PUSCH_MAPPING
printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n",
y_offset, nb_re_pssch, l, nb_rb);
#endif
}
#ifdef DEBUG_DFT_IDFT
int32_t debug_symbols[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
int offset = 0;
for (int ll = 0; ll < n_symbs; ll++) {
debug_symbols[ll] = slsch_ue->y[ll];
}
printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols, number_dmrs_symbols);
for (int ll = 0; ll < (number_of_symbols - number_dmrs_symbols); ll++) {
nr_idft(&debug_symbols[offset], nb_re_pusch);
offset = offset + nb_re_pusch;
}
LOG_M("preDFT_all_symbols.m", "UE_preDFT", tx_layers[0], number_of_symbols * nb_re_pssch, 1, 1);
LOG_M("postDFT_all_symbols.m", "UE_postDFT", y, number_of_symbols * nb_re_pssch, 1, 1);
LOG_M("DEBUG_IDFT_SYMBOLS.m", "UE_Debug_IDFT", debug_symbols, number_of_symbols * nb_re_pssch, 1, 1);
LOG_M("UE_DMRS_SEQ.m", "UE_DMRS_SEQ", dmrs_seq, nb_re_pusch, 1, 1);
#endif
}
////////////////////////////////////////////////////////////////////////
/////////////////////////ULSCH RE mapping/////////////////////////
///////////
int encoded_length = frame_parms->N_RB_UL*14*NR_NB_SC_PER_RB*mod_order*Nl;
int16_t **tx_precoding = (int16_t **)malloc16_clear(Nl*sizeof(int16_t *));
for (int nl=0; nl<Nl; nl++)
tx_precoding[nl] = (int16_t *)malloc16_clear((encoded_length<<1)*sizeof(int16_t));
for (int nl=0; nl < Nl; nl++) {
for (int nl = 0; nl < Nl; nl++) {
uint8_t k_prime = 0;
uint16_t m = 0;
#ifdef DEBUG_PUSCH_MAPPING
printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u);
#endif
int dmrs_port = get_dmrs_port(nl,pssch_pdu->dmrs_ports);
uint16_t m = M_SCI2_Layer;
uint16_t m0 = 0;
int dmrs_port = get_dmrs_port_sl(nl, pssch_pdu->dmrs_ports);
// DMRS params for this dmrs port
get_Wt(Wt, dmrs_port, dmrs_type);
get_Wf(Wf, dmrs_port, dmrs_type);
delta = get_delta(dmrs_port, dmrs_type);
for (int l=start_symbol; l<start_symbol+number_of_symbols; l++) {
get_Wt_sl(Wt, dmrs_port);
get_Wf_sl(Wf, dmrs_port);
delta = get_delta_sl(dmrs_port);
for (int l = start_symbol; l < number_of_symbols; l++) {
uint16_t k = start_sc;
uint16_t n = 0;
uint8_t is_dmrs_sym = 0;
uint8_t is_ptrs_sym = 0;
uint16_t dmrs_idx = 0, ptrs_idx = 0;
uint16_t dmrs_idx = 0;
if ((sl_dmrs_symb_pos >> l) & 0x01) {
is_dmrs_sym = 1;
if (pssch_pdu->transform_precoding == transformPrecoder_disabled){
if (dmrs_type == pusch_dmrs_type1)
dmrs_idx = (pssch_pdu->bwp_start + start_rb)*6;
else
dmrs_idx = (pssch_pdu->bwp_start + start_rb)*4;
if (pssch_pdu->transform_precoding == transformPrecoder_disabled) {
dmrs_idx = (bwp_start + start_rb) * 6;
// TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
// Perform this on gold sequence, not required when SC FDMA operation is done,
LOG_D(PHY,"DMRS in symbol %d\n",l);
nr_modulation(pssch_dmrs[l][pssch_pdu->scid], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
LOG_D(NR_PHY, "DMRS in symbol %d\n", l);
nr_modulation(pssch_dmrs[l], n_dmrs * 2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
} else {
dmrs_idx = 0;
}
} else if (pssch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
AssertFatal(pssch_pdu->transform_precoding == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n");
if(is_ptrs_symbol(l, slsch_ue->ptrs_symbols)) {
is_ptrs_sym = 1;
nr_modulation(pssch_dmrs[l][pssch_pdu->scid], nb_rb, DMRS_MOD_ORDER, mod_ptrs);
dmrs_idx = 0;
}
}
for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++) {
for (i = 0; i < nb_rb * NR_NB_SC_PER_RB; i++) {
uint8_t is_dmrs = 0;
uint8_t is_ptrs = 0;
sample_offsetF = l*frame_parms->ofdm_symbol_size + k;
sample_offsetF = l * frame_parms->ofdm_symbol_size + k;
if (is_dmrs_sym) {
if (k == ((start_sc+get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type))%frame_parms->ofdm_symbol_size))
if (k == ((start_sc + get_dmrs_freq_idx_ul(n, k_prime, delta, dmrs_type)) % frame_parms->ofdm_symbol_size))
is_dmrs = 1;
} else if (is_ptrs_sym) {
is_ptrs = is_ptrs_subcarrier(k,
rnti,
nl,
dmrs_type,
K_ptrs,
nb_rb,
pssch_pdu->pssch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
start_sc,
frame_parms->ofdm_symbol_size);
}
if (is_dmrs == 1) {
// if transform precoding is enabled
if (pssch_pdu->transform_precoding == transformPrecoder_enabled) {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15;
} else {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15;
}
((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1] = (Wt[l_prime[0]] * Wf[k_prime] * AMP * mod_dmrs[dmrs_idx << 1]) >> 15;
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1] = (Wt[l_prime[0]] * Wf[k_prime] * AMP * mod_dmrs[(dmrs_idx << 1) + 1]) >> 15;
#ifdef DEBUG_PUSCH_MAPPING
printf("DMRS: Layer: %d\t, dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n",
nl, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1],
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]);
nl, dmrs_idx, l, k, k_prime, n, ((int16_t*)tx_precoding[nl])[(sample_offsetF) << 1],
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1]);
#endif
dmrs_idx++;
k_prime++;
k_prime&=1;
n+=(k_prime)?0:1;
} else if (is_ptrs == 1) {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = (beta_ptrs*AMP*mod_ptrs[ptrs_idx<<1]) >> 15;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = (beta_ptrs*AMP*mod_ptrs[(ptrs_idx<<1) + 1]) >> 15;
ptrs_idx++;
} else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) {
if (pssch_pdu->transform_precoding == transformPrecoder_disabled) {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *)tx_layers[nl])[m<<1];
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *)tx_layers[nl])[(m<<1) + 1];
}
else {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = ((int16_t *) y)[m<<1];
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = ((int16_t *) y)[(m<<1) + 1];
}
k_prime &= 1;
n += (k_prime) ? 0 : 1;
} else if (!is_dmrs_sym) {
((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1] = ((int16_t *)tx_layers[nl])[m << 1];
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1] = ((int16_t *)tx_layers[nl])[(m << 1) + 1];
#ifdef DEBUG_PUSCH_MAPPING
printf("DATA: layer %d\t m %d\t l %d \t k %d \t tx_precoding: %d %d\n",
nl, m, l, k, ((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1],
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1]);
nl, m, l, k, ((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1],
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1]);
#endif
m++;
} else {
((int16_t*)tx_precoding[nl])[(sample_offsetF)<<1] = 0;
((int16_t*)tx_precoding[nl])[((sample_offsetF)<<1) + 1] = 0;
} else if ((is_dmrs_sym) && (is_dmrs != 1)) {
if (m0 < M_SCI2_Layer) {
((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1] = ((int16_t *)tx_layers[nl])[m0 << 1];
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1] = ((int16_t *)tx_layers[nl])[(m0 << 1) + 1];
m0++;
} else {
((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1] = ((int16_t *)tx_layers[nl])[m << 1];
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1] = ((int16_t *)tx_layers[nl])[(m << 1) + 1];
m++;
}
} else {
((int16_t *)tx_precoding[nl])[(sample_offsetF) << 1] = 0;
((int16_t *)tx_precoding[nl])[((sample_offsetF) << 1) + 1] = 0;
}
if (++k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
} //for (i=0; i< nb_rb*NR_NB_SC_PER_RB; i++)
}//for (l=start_symbol; l<start_symbol+number_of_symbols; l++)
}//for (nl=0; nl < Nl; nl++)
k -= frame_parms->ofdm_symbol_size;
} //for (i = 0; i < nb_rb * NR_NB_SC_PER_RB; i++)
}//for (l = start_symbol; l < start_symbol + number_of_symbols; l++)
}//for (nl = 0; nl < Nl; nl++)
/////SLSCH Mapping from virtual to physical resource blocks mapping/////
uint16_t nb_re_sci1 = NB_RB_SCI1 * NR_NB_SC_PER_RB;
/////////////////////////ULSCH precoding/////////////////////////
///////////
///Layer Precoding and Antenna port mapping
// tx_layers 0-3 are mapped on antenna ports
// The precoding info is supported by nfapi such as num_prgs, prg_size, prgs_list and pm_idx
// The same precoding matrix is applied on prg_size RBs, Thus
// pmi = prgs_list[rbidx/prg_size].pm_idx, rbidx =0,...,rbSize-1
// The Precoding matrix:
for (int ap=0; ap<frame_parms->nb_antennas_tx; ap++) {
for (int l=start_symbol; l<start_symbol+number_of_symbols; l++) {
uint16_t k = start_sc;
for (int ap = 0; ap < frame_parms->nb_antennas_tx; ap++) {
// Copying symbol 1 to symbol 0 (AGC)
memcpy(&txdataF[ap][start_sc],
&tx_precoding[ap][2 * (frame_parms->ofdm_symbol_size + start_sc)],
NR_NB_SC_PER_RB * sizeof(int32_t));
for (int rb=0; rb<nb_rb; rb++) {
for (int l = start_symbol; l < number_of_symbols; l++) {
uint16_t k;
if (1 <= l && l <= 3) { // Assumption there are three SLCCH symbols
k = start_sc + nb_re_sci1;
} else {
k = start_sc;
}
for (int rb = 0; rb < nb_rb; rb++) {
//get pmi info
uint8_t pmi=pssch_pdu->Tpmi;
uint8_t pmi = pssch_pdu->Tpmi;
if (pmi == 0) {//unitary Precoding
if (k + NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) { // RB does not cross DC
if (ap<pssch_pdu->nrOfLayers)
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
NR_NB_SC_PER_RB*sizeof(int32_t));
else
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
0,
NR_NB_SC_PER_RB*sizeof(int32_t));
} else { // RB does cross DC
int neg_length = frame_parms->ofdm_symbol_size - k;
int pos_length = NR_NB_SC_PER_RB - neg_length;
if (ap<pssch_pdu->nrOfLayers) {
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + k)],
neg_length*sizeof(int32_t));
memcpy(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
&tx_precoding[ap][2*(l*frame_parms->ofdm_symbol_size)],
pos_length*sizeof(int32_t));
if (ap < pssch_pdu->nrOfLayers) {
if (1 <= l && l <= 3)
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2 * (l * frame_parms->ofdm_symbol_size + k - nb_re_sci1)],
NR_NB_SC_PER_RB * sizeof(int32_t));
else
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2 * (l * frame_parms->ofdm_symbol_size + k)],
NR_NB_SC_PER_RB * sizeof(int32_t));
} else {
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size + k],
0,
neg_length*sizeof(int32_t));
memset(&txdataF[ap][l*frame_parms->ofdm_symbol_size],
0,
pos_length*sizeof(int32_t));
memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
0,
NR_NB_SC_PER_RB * sizeof(int32_t));
}
} else { // RB does cross DC
int neg_length = frame_parms->ofdm_symbol_size - k;
int pos_length = NR_NB_SC_PER_RB - neg_length;
if (ap < pssch_pdu->nrOfLayers) {
if (1 <= l && l <= 3)
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2 * (l * frame_parms->ofdm_symbol_size + k - nb_re_sci1)],
neg_length * sizeof(int32_t));
else
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
&tx_precoding[ap][2 * (l * frame_parms->ofdm_symbol_size + k)],
neg_length * sizeof(int32_t));
memcpy(&txdataF[ap][l * frame_parms->ofdm_symbol_size],
&tx_precoding[ap][2 * (l * frame_parms->ofdm_symbol_size)],
pos_length * sizeof(int32_t));
} else {
memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size + k],
0,
neg_length * sizeof(int32_t));
memset(&txdataF[ap][l * frame_parms->ofdm_symbol_size],
0,
pos_length * sizeof(int32_t));
}
}
k += NR_NB_SC_PER_RB;
if (k >= frame_parms->ofdm_symbol_size) {
k -= frame_parms->ofdm_symbol_size;
}
}
else {
//get the precoding matrix weights:
char *W_prec;
switch (frame_parms->nb_antennas_tx) {
case 1://1 antenna port
W_prec = nr_W_1l_2p[pmi][ap];
break;
case 2://2 antenna ports
if (pssch_pdu->nrOfLayers == 1)//1 layer
W_prec = nr_W_1l_2p[pmi][ap];
else//2 layers
W_prec = nr_W_2l_2p[pmi][ap];
break;
case 4://4 antenna ports
if (pssch_pdu->nrOfLayers == 1)//1 layer
W_prec = nr_W_1l_4p[pmi][ap];
else if (pssch_pdu->nrOfLayers == 2)//2 layers
W_prec = nr_W_2l_4p[pmi][ap];
else if (pssch_pdu->nrOfLayers == 3)//3 layers
W_prec = nr_W_3l_4p[pmi][ap];
else//4 layers
W_prec = nr_W_4l_4p[pmi][ap];
break;
default:
LOG_D(PHY,"Precoding 1,2, or 4 antenna ports are currently supported\n");
W_prec = nr_W_1l_2p[pmi][ap];
break;
}
for (int i=0; i<NR_NB_SC_PER_RB; i++) {
int32_t re_offset = l*frame_parms->ofdm_symbol_size + k;
int32_t precodatatx_F = nr_layer_precoder(tx_precoding, W_prec, pssch_pdu->nrOfLayers, re_offset);
((int16_t*)txdataF[ap])[(re_offset<<1)] = ((int16_t *) &precodatatx_F)[0];
((int16_t*)txdataF[ap])[(re_offset<<1) + 1] = ((int16_t *) &precodatatx_F)[1];
if (++k >= frame_parms->ofdm_symbol_size) {
k -= frame_parms->ofdm_symbol_size;
}
}
}
} //RB loop
} // symbol loop
}// port loop
} // port loop
NR_UL_UE_HARQ_t *harq_process_slsch=NULL;
NR_UL_UE_HARQ_t *harq_process_slsch = NULL;
harq_process_slsch = UE->slsch[thread_id][gNB_id]->harq_processes[harq_pid];
harq_process_slsch->status = SCH_IDLE;
@@ -617,10 +456,7 @@ void nr_ue_slsch_tx_procedures(PHY_VARS_NR_UE *UE,
}
free_and_zero(tx_layers);
free_and_zero(tx_precoding);
///////////
////////////////////////////////////////////////////////////////////////
}

View File

@@ -95,6 +95,7 @@
/// suppress compiler warning for unused arguments
#define UNUSED(x) (void)x;
#define NB_RB_SCI1 20
#include "impl_defs_top.h"
#include "impl_defs_nr.h"
#include "time_meas.h"

View File

@@ -413,11 +413,14 @@ typedef struct {
/* NR Sidelink PSSCH SCI2 payload fields */
typedef struct {
//TODO: update the following
uint32_t coverageIndicator : 1;
uint32_t tddConfig : 12;
uint32_t DFN : 10;
uint32_t slotIndex : 7;
uint32_t reserved : 2;
uint32_t harq_pid : 4;
uint32_t ndi : 1;
uint32_t red_version : 2;
uint32_t s_id : 8;
uint32_t d_id : 16;
uint32_t harq_fdbk_enabled : 1;
uint32_t ctype_ind : 2;
uint32_t csi_request : 1;
} PSSCH_SCI2_payload;
/// Enumeration of SL_channel_config

View File

@@ -40,7 +40,9 @@
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "openair1/PHY/NR_UE_TRANSPORT/nr_slsch.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "SCHED_NR/sched_nr.h"
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/RF/rf.h"