Commit 64ed4e92 authored by francescomani's avatar francescomani

handling beams in PHY TX channels

parent 7e82854b
......@@ -39,6 +39,7 @@
#include "PHY/defs_common.h"
#define NR_MAX_PDSCH_TBS 3824
#define MAX_NUM_BEAM_PERIODS 4
#define MAX_BWP_SIZE 275
#define NR_MAX_NUM_BWP 4
#define NR_MAX_HARQ_PROCESSES 32
......
......@@ -538,9 +538,11 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot_tx );
}
if (ru->feptx_ofdm) ru->feptx_ofdm(ru,frame_tx,slot_tx);
if (ru->feptx_ofdm)
ru->feptx_ofdm(ru, frame_tx, slot_tx);
if (ru->fh_south_out) ru->fh_south_out(ru,frame_tx,slot_tx,proc->timestamp_tx);
if (ru->fh_south_out)
ru->fh_south_out(ru, frame_tx, slot_tx, proc->timestamp_tx);
}
void fh_if5_north_out(RU_t *ru) {
......@@ -715,7 +717,7 @@ static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot)
if (ru->common.beam_id) {
int prev_slot = (slot - 1 + fp->slots_per_frame) % fp->slots_per_frame;
const uint8_t *beam_ids = ru->common.beam_id[0];
const int *beam_ids = ru->common.beam_id[0];
int prev_beam = beam_ids[prev_slot * fp->symbols_per_slot];
int beam = beam_ids[slot * fp->symbols_per_slot];
if (prev_beam != beam) {
......@@ -1041,7 +1043,7 @@ void ru_tx_func(void *param)
int slot_tx = info->slot_tx;
int print_frame = 8;
char filename[40];
int cumul_samples = fp->get_samples_per_slot(0, fp);
int i = 1;
for (; i < fp->slots_per_subframe / 2; i++)
......@@ -1052,10 +1054,12 @@ void ru_tx_func(void *param)
int rt_prof_idx = absslot_rx % RT_PROF_DEPTH;
clock_gettime(CLOCK_MONOTONIC,&ru->rt_ru_profiling.start_RU_TX[rt_prof_idx]);
// do TX front-end processing if needed (precoding and/or IDFTs)
if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx);
if (ru->feptx_prec)
ru->feptx_prec(ru,frame_tx,slot_tx);
// do OFDM with/without TX front-end processing if needed
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx);
if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm))
ru->feptx_ofdm(ru, frame_tx, slot_tx);
if(!emulate_rf) {
// do outgoing fronthaul (south) if needed
......
......@@ -41,7 +41,6 @@
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
int l1_north_init_gNB() {
if (RC.nb_nr_L1_inst > 0 && RC.gNB != NULL) {
......@@ -104,7 +103,7 @@ void reset_active_stats(PHY_VARS_gNB *gNB, int frame)
// A global var to reduce the changes size
ldpc_interface_t ldpc_interface = {0}, ldpc_interface_offload = {0};
int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
{
// shortcuts
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
......@@ -112,16 +111,24 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
NR_gNB_PRACH *const prach_vars = &gNB->prach_vars;
int i;
int Ptx=cfg->carrier_config.num_tx_ant.value;
int Prx=cfg->carrier_config.num_rx_ant.value;
common_vars->analog_bf = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value;
LOG_I(PHY, "L1 configured with%s analog beamforming\n", common_vars->analog_bf ? "" : "out");
if (common_vars->analog_bf) {
common_vars->num_beams_period = cfg->analog_beamforming_ve.num_beams_period_vendor_ext.value;
LOG_I(PHY, "Max number of concurrent beams: %d\n", common_vars->num_beams_period);
} else
common_vars->num_beams_period = 1;
int Ptx = cfg->carrier_config.num_tx_ant.value;
int Prx = cfg->carrier_config.num_rx_ant.value;
int max_ul_mimo_layers = 4;
AssertFatal(Ptx>0 && Ptx<9,"Ptx %d is not supported\n",Ptx);
AssertFatal(Prx>0 && Prx<9,"Prx %d is not supported\n",Prx);
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
AssertFatal(Ptx > 0 && Ptx < 9,"Ptx %d is not supported\n", Ptx);
AssertFatal(Prx > 0 && Prx < 9,"Prx %d is not supported\n", Prx);
LOG_I(PHY, "[gNB %d]About to wait for gNB to be configured\n", gNB->Mod_id);
while(gNB->configured == 0) usleep(10000);
while(gNB->configured == 0)
usleep(10000);
load_dftslib();
......@@ -172,19 +179,21 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
}
}
common_vars->txdataF = (c16_t **)malloc16(Ptx*sizeof(c16_t*));
common_vars->rxdataF = (c16_t **)malloc16(Prx*sizeof(c16_t*));
/* Do NOT allocate per-antenna txdataF/rxdataF: the gNB gets a pointer to the
/* Do NOT allocate per-antenna rxdataF: the gNB gets a pointer to the
* RU to copy/recover freq-domain memory from there */
common_vars->beam_id = (uint8_t **)malloc16(Ptx*sizeof(uint8_t*));
for (i=0;i<Ptx;i++){
common_vars->txdataF[i] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(c16_t)); // [hna] samples_per_frame without CP
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
i,common_vars->txdataF[i],
fp->samples_per_frame_wCP*sizeof(c16_t));
common_vars->beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t));
memset(common_vars->beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame);
common_vars->rxdataF = (c16_t **)malloc16(Prx * sizeof(c16_t*));
common_vars->num_beams = cfg->dbt_config.num_dig_beams;
if (common_vars->num_beams > 0) {
common_vars->beam_id = (int **)malloc16(common_vars->num_beams_period * sizeof(int*));
for (int i = 0; i < common_vars->num_beams_period; i++)
common_vars->beam_id[i] = (int*)malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
}
common_vars->txdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**));
for (int i = 0; i < common_vars->num_beams_period; i++) {
common_vars->txdataF[i] = (c16_t**)malloc16_clear(Ptx * sizeof(c16_t*));
for (int j = 0; j < Ptx; j++)
common_vars->txdataF[i][j] = (c16_t*)malloc16_clear(fp->samples_per_frame_wCP * sizeof(c16_t));
}
common_vars->debugBuff = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t)*100);
common_vars->debugBuff_sample_offset = 0;
......@@ -209,14 +218,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
pusch->ul_ch_estimates_time = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->rxdataF_comp = (int32_t **)malloc16(n_buf * sizeof(int32_t *));
pusch->llr_layers = (int16_t **)malloc16(max_ul_mimo_layers * sizeof(int32_t *));
for (i = 0; i < n_buf; i++) {
for (int i = 0; i < n_buf; i++) {
pusch->ul_ch_estimates[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size * fp->symbols_per_slot);
pusch->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->ofdm_symbol_size);
pusch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * fp->symbols_per_slot); // symbols per slot
pusch->rxdataF_comp[i] = (int32_t *)malloc16_clear(sizeof(int32_t) * nb_re_pusch2 * fp->symbols_per_slot);
}
for (i=0; i< max_ul_mimo_layers; i++) {
for (int i = 0; i < max_ul_mimo_layers; i++) {
pusch->llr_layers[i] = (int16_t *)malloc16_clear((8 * ((3 * 8 * 6144) + 12))
* sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
}
......@@ -224,8 +233,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
* sizeof(int16_t)); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
pusch->ul_valid_re_per_slot = (int16_t *)malloc16_clear(sizeof(int16_t) * fp->symbols_per_slot);
} // ulsch_id
return (0);
}
void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
......@@ -258,9 +265,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
reset_nr_transport(gNB);
NR_gNB_COMMON * common_vars = &gNB->common_vars;
for (int i = 0; i < Ptx; i++) {
free_and_zero(common_vars->txdataF[i]);
free_and_zero(common_vars->beam_id[i]);
for (int j = 0; j < common_vars->num_beams_period; j++) {
if (common_vars->beam_id)
free_and_zero(common_vars->beam_id[j]);
for (int i = 0; i < Ptx; i++) {
free_and_zero(common_vars->txdataF[j][i]);
}
free_and_zero(common_vars->txdataF[j]);
}
/* Do NOT free per-antenna txdataF/rxdataF: the gNB gets a pointer to the
......
......@@ -42,17 +42,14 @@ int nr_phy_init_RU(RU_t *ru)
ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value;
}
ru->analog_beamforming = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value;
LOG_I(PHY, "RU configured with%s analog beamforming\n", ru->analog_beamforming ? "" : "out");
// copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration
// (at least the parts that are needed by the RU, numerology and PRACH)
AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas);
ru->common.beam_id = malloc16_clear(ru->nb_log_antennas * sizeof(uint8_t*));
for(int i = 0; i < ru->nb_tx; ++i)
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(uint8_t));
ru->common.beam_id = malloc16_clear(MAX_NUM_BEAM_PERIODS * sizeof(int*));
for(int i = 0; i < MAX_NUM_BEAM_PERIODS; i++)
ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int));
if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals
// Time-domain signals
......@@ -178,7 +175,7 @@ void nr_phy_free_RU(RU_t *ru)
free_and_zero(ru->prach_rxsigF[j][i]);
free_and_zero(ru->prach_rxsigF[j]);
}
for(int i = 0; i < ru->nb_log_antennas; ++i)
for(int i = 0; i < MAX_NUM_BEAM_PERIODS; ++i)
free_and_zero(ru->common.beam_id[i]);
free_and_zero(ru->common.beam_id);
}
......
......@@ -38,7 +38,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
void init_N_TA_offset(PHY_VARS_NR_UE *ue);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
int phy_init_nr_gNB(PHY_VARS_gNB *gNB);
void phy_init_nr_gNB(PHY_VARS_gNB *gNB);
int init_codebook_gNB(PHY_VARS_gNB *gNB);
void nr_phy_config_request(NR_PHY_Config_t *gNB);
void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,int N_RB_DL,int N_RB_UL,int mu,int Nid_cell,uint64_t position_in_burst);
......
......@@ -36,6 +36,7 @@
#include "nr_sch_dmrs.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "common/utils/nr/nr_common.h"
#include "SCHED_NR/sched_nr.h"
//#define DEBUG_PDCCH_DMRS
//#define DEBUG_DCI
......@@ -50,17 +51,12 @@ static void nr_pdcch_scrambling(uint32_t *in, uint32_t size, uint32_t Nid, uint3
out[i] = in[i] ^ seq[i];
}
void nr_generate_dci(PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS *frame_parms,
int slot) {
uint16_t cset_start_sc;
uint8_t cset_start_symb, cset_nsymb;
int k,l,k_prime,dci_idx, dmrs_idx;
static void nr_generate_dci(PHY_VARS_gNB *gNB,
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
int txdataF_offset,
NR_DL_FRAME_PARMS *frame_parms,
int slot)
{
// fill reg list per symbol
int reg_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL * NR_NB_REG_PER_CCE];
nr_fill_reg_list(reg_list, pdcch_pdu_rel15);
......@@ -68,20 +64,29 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
int rb_offset;
int n_rb;
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
uint16_t cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
int idx1 = pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols;
int idx2 = (((n_rb + rb_offset + pdcch_pdu_rel15->BWPStart) * 6 + 15) >> 4) << 4;
int16_t mod_dmrs[idx1][idx2] __attribute__((aligned(16)));
int16_t mod_dmrs[pdcch_pdu_rel15->StartSymbolIndex+pdcch_pdu_rel15->DurationSymbols][(((n_rb+rb_offset+pdcch_pdu_rel15->BWPStart)*6+15)>>4)<<4] __attribute__((aligned(16))); // 3 for the max coreset duration
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
for (int d = 0; d < pdcch_pdu_rel15->numDlDci; d++) {
/*The coreset is initialised
* in frequency: the first subcarrier is obtained by adding the first CRB overlapping the SSB and the rb_offset for coreset 0
* or the rb_offset for other coresets
* in time: by its first slot and its first symbol*/
const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d];
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
dci_idx = 0;
uint32_t cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
uint32_t cset_nsymb = pdcch_pdu_rel15->DurationSymbols;
int dci_idx = 0;
// multi-beam number (for concurrent beams)
int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->common_vars,
slot,
frame_parms->symbols_per_slot,
cset_start_symb,
pdcch_pdu_rel15->DurationSymbols);
LOG_D(NR_PHY_DCI, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n", rb_offset, n_rb, pdcch_pdu_rel15->BWPStart);
LOG_D(NR_PHY_DCI,
"pdcch: Coreset starting subcarrier %d on symbol %d (%d symbols)\n",
......@@ -107,16 +112,18 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset
/// DMRS QPSK modulation
for (int symb=cset_start_symb; symb<cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
for (int symb = cset_start_symb; symb < cset_start_symb + pdcch_pdu_rel15->DurationSymbols; symb++) {
const uint32_t *gold = nr_gold_pdcch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, dci_pdu->ScramblingId, slot, symb);
nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER,
mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
nr_modulation(gold, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); // Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_PDCCH_DMRS
if(dci_pdu->RNTI!=0xFFFF) {
for (int i=0; i<dmrs_length>>1; i++)
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i,
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]);
printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n",
symb,
i,
&gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5],
mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]);
}
#endif
}
......@@ -163,7 +170,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
#endif
/// Resource mapping
uint16_t amp = gNB->TX_AMP;
int32_t *txdataF = (int32_t *)&gNB->common_vars.txdataF[beam_nb][0][txdataF_offset];
if (cset_start_sc >= frame_parms->ofdm_symbol_size)
cset_start_sc -= frame_parms->ofdm_symbol_size;
......@@ -172,20 +180,21 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
for(int symbol_idx = 0; symbol_idx < pdcch_pdu_rel15->DurationSymbols; symbol_idx++) {
// allocating rbs per symbol
for (int reg_count = 0; reg_count < num_regs; reg_count++) {
k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB;
int k = cset_start_sc + reg_list[d][reg_count] * NR_NB_SC_PER_RB;
LOG_D(NR_PHY_DCI, "REG %d k %d\n", reg_list[d][reg_count], k);
if (k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
l = cset_start_symb + symbol_idx;
int l = cset_start_symb + symbol_idx;
// dmrs index depends on reference point for k according to 38.211 7.4.1.3.2
int dmrs_idx;
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
dmrs_idx = (reg_list[d][reg_count] + pdcch_pdu_rel15->BWPStart) * 3;
else
dmrs_idx = (reg_list[d][reg_count] + rb_offset) * 3;
k_prime = 0;
int k_prime = 0;
for (int m = 0; m < NR_NB_SC_PER_RB; m++) {
if (m == (k_prime << 2) + 1) { // DMRS if not already mapped
......@@ -235,16 +244,13 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
}
void nr_generate_dci_top(processingData_L1tx_t *msgTx,
int slot,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS *frame_parms) {
for (int i=0; i<msgTx->num_ul_pdcch; i++)
nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
for (int i=0; i<msgTx->num_dl_pdcch; i++)
nr_generate_dci(msgTx->gNB,&msgTx->pdcch_pdu[i].pdcch_pdu_rel15,txdataF,amp,frame_parms,slot);
void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset)
{
PHY_VARS_gNB *gNB = msgTx->gNB;
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
for (int i = 0; i < msgTx->num_ul_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
for (int i = 0; i < msgTx->num_dl_pdcch; i++)
nr_generate_dci(msgTx->gNB, &msgTx->pdcch_pdu[i].pdcch_pdu_rel15, txdataF_offset, frame_parms, slot);
}
......@@ -26,11 +26,7 @@
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
void nr_generate_dci_top(processingData_L1tx_t *msgTx,
int slot,
int32_t *txdataF,
int16_t amp,
NR_DL_FRAME_PARMS *frame_parms);
void nr_generate_dci_top(processingData_L1tx_t *msgTx, int slot, int txdataF_offset);
int16_t find_nr_pdcch(int frame,int slot, PHY_VARS_gNB *gNB,find_type_t type);
......
......@@ -39,6 +39,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/nr/nr_common.h"
#include "executables/softmodem-common.h"
#include "SCHED_NR/sched_nr.h"
//#define DEBUG_DLSCH
//#define DEBUG_DLSCH_MAPPING
......@@ -468,7 +469,16 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
// The Precoding matrix:
// The Codebook Type I
start_meas(&gNB->dlsch_precoding_stats);
c16_t **txdataF = gNB->common_vars.txdataF;
nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
// beam number in multi-beam scenario (concurrent beams)
int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx,
&gNB->common_vars,
slot,
frame_parms->symbols_per_slot,
rel15->StartSymbolIndex,
rel15->NrOfSymbols);
c16_t **txdataF = gNB->common_vars.txdataF[beam_nb];
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
for (int l_symbol = rel15->StartSymbolIndex; l_symbol < rel15->StartSymbolIndex + rel15->NrOfSymbols; l_symbol++) {
......@@ -477,10 +487,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
int rb = 0;
while(rb < rel15->rbSize) {
//get pmi info
const int pmi = (rel15->precodingAndBeamforming.prg_size > 0) ?
(rel15->precodingAndBeamforming.prgs_list[(int)rb/rel15->precodingAndBeamforming.prg_size].pm_idx) : 0;
const int pmi2 = (rb < (rel15->rbSize - 1) && rel15->precodingAndBeamforming.prg_size > 0) ?
(rel15->precodingAndBeamforming.prgs_list[(int)(rb+1)/rel15->precodingAndBeamforming.prg_size].pm_idx) : -1;
const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb+1)/pb->prg_size].pm_idx) : -1;
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
......@@ -576,21 +584,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot)
stop_meas(&gNB->dlsch_precoding_stats);
// TODO: handle precoding
// this maps the layers onto antenna ports
// handle beamforming ID
// each antenna port is assigned a beam_index
// since PHY can only handle BF on slot basis we set the whole slot
// first check if this slot has not already been allocated to another beam
if (gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot]==255) {
for (int j=0;j<frame_parms->symbols_per_slot;j++)
gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
}
else {
LOG_D(PHY,"beam index for PDSCH allocation already taken\n");
}
}// dlsch loop
}
......
......@@ -130,9 +130,9 @@ typedef struct {
/// - third index: frequency [0..]
int32_t **tdd_calib_coeffs;
/// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
/// - first index: antenna port
/// - first index: concurrent beam
/// - second index: beam_id [0.. symbols_per_frame[
uint8_t **beam_id;
int **beam_id;
} RU_COMMON;
......@@ -663,7 +663,6 @@ typedef struct RU_t_s {
/// structure for analyzing high-level RT measurements
rt_ru_profiling_t rt_ru_profiling;
void* scopeData;
bool analog_beamforming;
} RU_t;
......
......@@ -269,14 +269,17 @@ typedef struct {
c16_t **rxdataF;
/// \brief holds the transmit data in the frequency domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
/// - first index: eNB id [0..2] (hard coded)
/// - first index: beam (for concurrent beams)
/// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
/// - third index: sample [0..samples_per_frame_woCP]
c16_t **txdataF;
c16_t ***txdataF;
/// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU)
/// - first index: antenna port
/// - first index: beam index (for concurrent beams)
/// - second index: beam_id [0.. symbols_per_frame[
uint8_t **beam_id;
int **beam_id;
int num_beams;
int num_beams_period;
bool analog_bf;
int32_t *debugBuff;
int32_t debugBuff_sample_offset;
} NR_gNB_COMMON;
......
......@@ -198,22 +198,23 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int tti_tx)
gNB = gNB_list[0];
if (ru->config.dbt_config.num_dig_beams != 0) {
for(int i = 0; i < ru->nb_log_antennas; ++i) {
for(int i = 0; i < gNB->common_vars.num_beams_period; ++i) {
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
(void*) &gNB->common_vars.beam_id[i][slot_tx * fp->symbols_per_slot],
(fp->symbols_per_slot) * sizeof(uint8_t));
(fp->symbols_per_slot) * sizeof(int));
}
}
if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming) {
for (int i = 0; i < ru->nb_log_antennas; ++i)
memcpy(ru->common.txdataF_BF[i], &gNB->common_vars.txdataF[i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
if (ru->config.dbt_config.num_dig_beams == 0 || gNB->common_vars.analog_bf) {
for (int i = 0; i < ru->nb_log_antennas; ++i) {
// TODO hardcoded beam to 0, still need to understand how to handle this properly
memcpy(ru->common.txdataF_BF[i], &gNB->common_vars.txdataF[0][i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
}
}
else {
for(int i = 0; i < ru->nb_log_antennas; ++i) {
memcpy((void*)ru->common.txdataF[i],
(void*)&gNB->common_vars.txdataF[i][txdataF_offset],
fp->samples_per_slot_wCP * sizeof(int32_t));
// TODO hardcoded beam to 0, still need to understand how to handle this properly
memcpy(ru->common.txdataF[i], &gNB->common_vars.txdataF[0][i][txdataF_offset], fp->samples_per_slot_wCP * sizeof(int32_t));
}
for (int l = 0; l < fp->symbols_per_slot; l++) {
for (int aa = 0; aa < ru->nb_tx; aa++) {
......@@ -255,17 +256,17 @@ void nr_feptx(void *arg)
start_meas(&ru->precoding_stats);
if (ru->config.dbt_config.num_dig_beams != 0) {
for(int i = 0; i < ru->nb_log_antennas; ++i) {
memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot],
(void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot],
(fp->symbols_per_slot)*sizeof(uint8_t));
for(int i = 0; i < ru->gNB_list[0]->common_vars.num_beams_period; i++) {
memcpy(&ru->common.beam_id[i][slot * fp->symbols_per_slot],
&ru->gNB_list[0]->common_vars.beam_id[i][slot * fp->symbols_per_slot],
(fp->symbols_per_slot) * sizeof(int));
}
}
// If there is no digital beamforming we just need to copy the data to RU
if (ru->config.dbt_config.num_dig_beams == 0 || ru->analog_beamforming)
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf)
memcpy((void*)&ru->common.txdataF_BF[aa][txdataF_BF_offset],
(void*)&ru->gNB_list[0]->common_vars.txdataF[aa][txdataF_offset],
(void*)&ru->gNB_list[0]->common_vars.txdataF[0][aa][txdataF_offset], // TODO hardcoded beam to 0, still need to understand how to handle this properly
numSamples * sizeof(int32_t));
else {
AssertFatal(false, "This needs to be fixed by using appropriate beams from config\n");
......@@ -301,28 +302,28 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot)
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM, 1);
start_meas(&ru->ofdm_total_stats);
for (int aid = 0; aid < ru->nb_tx; aid++) {
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx);
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
feptx_cmd->aid = aid;
feptx_cmd->ru = ru;
feptx_cmd->slot = slot;
feptx_cmd->startSymbol = 0;
feptx_cmd->numSymbols = (ru->half_slot_parallelization > 0) ?
ru->nr_frame_parms->symbols_per_slot >> 1 :
ru->nr_frame_parms->symbols_per_slot;
pushTpool(ru->threadPool, req);
nbfeptx++;
if (ru->half_slot_parallelization > 0) {
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx);
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
feptx_cmd->aid = aid;
feptx_cmd->ru = ru;
feptx_cmd->slot = slot;
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
pushTpool(ru->threadPool, req);
nbfeptx++;
}
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid, ru->respfeptx, nr_feptx);
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
feptx_cmd->aid = aid;
feptx_cmd->ru = ru;
feptx_cmd->slot = slot;
feptx_cmd->startSymbol = 0;
feptx_cmd->numSymbols = (ru->half_slot_parallelization > 0) ?
ru->nr_frame_parms->symbols_per_slot >> 1 :
ru->nr_frame_parms->symbols_per_slot;
pushTpool(ru->threadPool, req);
nbfeptx++;
if (ru->half_slot_parallelization > 0) {
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(feptx_cmd_t), 2000 + aid + ru->nb_tx, ru->respfeptx, nr_feptx);
feptx_cmd_t *feptx_cmd = (feptx_cmd_t*)NotifiedFifoData(req);
feptx_cmd->aid = aid;
feptx_cmd->ru = ru;
feptx_cmd->slot = slot;
feptx_cmd->startSymbol = ru->nr_frame_parms->symbols_per_slot >> 1;
feptx_cmd->numSymbols = ru->nr_frame_parms->symbols_per_slot >> 1;
pushTpool(ru->threadPool, req);
nbfeptx++;
}
}
while (nbfeptx > 0) {
notifiedFIFO_elt_t *req=pullTpool(ru->respfeptx, ru->threadPool);
......
This diff is collapsed.
......@@ -39,7 +39,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx);
void nr_fep_tp(RU_t *ru, int slot);
......@@ -47,5 +46,10 @@ void nr_feptx_tp(RU_t *ru, int frame_tx, int slot);
void feptx_prec(RU_t *ru,int frame_tx,int tti_tx);
int nr_phy_init_RU(RU_t *ru);
void nr_phy_free_RU(RU_t *ru);
int beam_index_allocation(int fapi_beam_index,
NR_gNB_COMMON *common_vars,
int slot,
int symbols_per_slot,
int start_symbol,
int nb_symbols);
#endif
......@@ -1042,24 +1042,33 @@ int main(int argc, char **argv)
int txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
if (n_trials==1) {
LOG_M("txsigF0.m","txsF0=", &gNB->common_vars.txdataF[0][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
LOG_M("txsigF0.m","txsF0=",
&gNB->common_vars.txdataF[0][0][txdataF_offset +2 * frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
1,
1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
LOG_M("txsigF1.m","txsF1=",
&gNB->common_vars.txdataF[0][1][txdataF_offset + 2 * frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
1,
1);
}
if (n_trials == 1) printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset);
if (n_trials == 1)
printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset);
//TODO: loop over slots
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[aa][txdataF_offset],
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][txdataF_offset],
(int *)&txdata[aa][slot_offset],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
nr_normal_prefix_mod(&gNB->common_vars.txdataF[0][aa][txdataF_offset],
&txdata[aa][slot_offset],
14,
frame_parms,
......
......@@ -640,49 +640,45 @@ int main(int argc, char **argv)
int slot = start_symbol/14;
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
memset(gNB->common_vars.txdataF[0][aa], 0, frame_parms->samples_per_slot_wCP * sizeof(int32_t));
nr_common_signal_procedures (gNB,frame,slot,msgDataTx.ssb[i].ssb_pdu);
int samp = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
apply_nr_rotation_TX(frame_parms,
gNB->common_vars.txdataF[aa],
gNB->common_vars.txdataF[0][aa],
frame_parms->symbol_rotation[0],
slot,
frame_parms->N_RB_DL,
0,
12);
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[aa],
(int *)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa],
(int *)&txdata[aa][samp],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
apply_nr_rotation_TX(frame_parms,
gNB->common_vars.txdataF[aa],
gNB->common_vars.txdataF[0][aa],
frame_parms->symbol_rotation[0],
slot,
frame_parms->N_RB_DL,
0,
14);
/*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
14,
frame_parms);*/
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[aa],
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
PHY_ofdm_mod((int *)gNB->common_vars.txdataF[0][aa],
(int*)&txdata[aa][samp],
frame_parms->ofdm_symbol_size,
1,
frame_parms->nb_prefix_samples0,
CYCLIC_PREFIX);
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[0][aa][frame_parms->ofdm_symbol_size],
(int*)&txdata[aa][samp + frame_parms->nb_prefix_samples0 + frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
13,
frame_parms->nb_prefix_samples,
......@@ -691,9 +687,9 @@ int main(int argc, char **argv)
}
}
}
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0][0],frame_length_complex_samples_no_prefix, 1, 1);
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[0][1],frame_length_complex_samples_no_prefix, 1, 1);
} else {
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
......
......@@ -544,7 +544,7 @@ int main(int argc, char **argv)
ack_nack_errors=0;
sr_errors=0;
n_errors = 0;
c16_t **txdataF = gNB->common_vars.txdataF;
c16_t **txdataF = gNB->common_vars.txdataF[0];
for (trial=0; trial<n_trials; trial++) {
for (int aatx=0;aatx<1;aatx++)
bzero(txdataF[aatx],frame_parms->ofdm_symbol_size*sizeof(int));
......
......@@ -34,7 +34,6 @@
#define __NR_RRC_PARAMSVALUES__H__
#include "common/config/config_paramdesc.h"
#include "NR_ServingCellConfigCommon.h"
/* cell configuration section name */
#define GNB_CONFIG_STRING_GNB_LIST "gNBs"
......
......@@ -532,8 +532,6 @@ static void config_common(gNB_MAC_INST *nrmac,
nr_pdsch_AntennaPorts_t pdsch_AntennaPorts = config->pdsch_AntennaPorts;
int num_pdsch_antenna_ports = pdsch_AntennaPorts.N1 * pdsch_AntennaPorts.N2 * pdsch_AntennaPorts.XP;
cfg->carrier_config.num_tx_ant.value = num_pdsch_antenna_ports;
if(nrmac->beam_info.beam_allocation) // analog beamforming
cfg->carrier_config.num_tx_ant.value *= nrmac->beam_info.beams_per_period;
AssertFatal(num_pdsch_antenna_ports > 0 && num_pdsch_antenna_ports < 33, "pdsch_AntennaPorts in 1...32\n");
cfg->carrier_config.num_tx_ant.tl.tag = NFAPI_NR_CONFIG_NUM_TX_ANT_TAG;
......
......@@ -100,7 +100,6 @@
#define MAX_NUM_OF_SSB 64
#define MAX_NUM_NR_PRACH_PREAMBLES 64
#define MIN_NUM_PRBS_TO_SCHEDULE 5
#define MAX_NUM_BEAM_PERIODS 4
extern const uint8_t nr_rv_round_map[4];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment