Commit 93b3a5ae authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/srs_phy_simulator' into integration_2026_w03 (!3718)

Introduce SRS physical simulator and improvements

This MR consists of two parts:

- Introduces SRS physical simulator to test different configurations of
  SRS
- Improvements in the SRS channel estimation (Addressing the comments
  from old, unfinished MR !2875)
  - rewrite nr_srs_channel_estimation() to loop over rx antennas and
    antenna ports to be able to parallelize
  - Improvements in timing_advance_offset and timing_advance_offset_nsec
    computation
  - Introduce SRS multi-symbol channel estimation
    - The channel impulse response is estimated from the averaged
      channel frequency response over multiple symbols
    - The channel frequency estimates are left as they are to be able to
      estimate doppler in the future
  - Simplify SRS channel estimation to handle memory alignment in the
    case of different SRS configurations (eg: comboffset)

To use multiple symbols when running gNB, the following parameters needs
to be edited in the function get_srs_resource()

- srs_res->resourceMapping.startPosition with a range from {0,1,..,5}
  corresponds to the start symbol {13, 12, .. 8} with in a slot
- srs_res->resourceMapping.nrofSymbols indicates the number of symbols
  {n1, n2, and n4}

Make sure the that start symbol + number of symbols is < 14

The timing results for SRS in develop and srs_phy_simulator are as follows:

Command used: sudo ./nr_ulsim -n1000 -s50 -S50 -R273 -W2 -y2 -z2 -E 1 -P

develop

|__ RX SRS time                            124.94 us (1000 trials)		(124.94 total [ms])
    |__ Generate SRS sequence time           0.05 us (1000 trials)		(  0.05 total [ms])
    |__ Get SRS signal time                 19.41 us (1000 trials)		( 19.41 total [ms])
    |__ SRS channel estimation time         89.11 us (1000 trials)		( 89.11 total [ms])
    |__ SRS timing advance estimation time  13.10 us (1000 trials)		( 13.10 total [ms])
    |__ SRS report TLV build time            2.80 us (1000 trials)		(  2.80 total [ms])
        |__ SRS beam report build time       0.00 us (  0 trials)
        |__ SRS IQ matrix build time         2.73 us (1000 trials)

srs_phy_simulator

|__ RX SRS time                            211.93 us (1000 trials)		(211.93 total [ms])
    |__ Generate SRS sequence time           0.04 us (1000 trials)		(  0.04 total [ms])
    |__ Get SRS signal time                 19.55 us (1000 trials)		( 19.55 total [ms])
    |__ SRS channel estimation time        152.05 us (1000 trials)		(152.05 total [ms])
    |__ SRS timing advance estimation time  36.67 us (1000 trials)		( 36.67 total [ms])
    |__ SRS report TLV build time            2.96 us (1000 trials)		(  2.96 total [ms])
        |__ SRS beam report build time       0.00 us (  0 trials)
        |__ SRS IQ matrix build time         2.88 us (1000 trials)

Note that in srs_phy_simulator, to compute timing offset ns, an
oversampling factor of 2 is performed. Also, for peak detection, we
average the channel estimates for every port.
parents 0fdc095d 5d545a6c
...@@ -2037,6 +2037,19 @@ target_link_libraries(nr_ulsim PRIVATE ...@@ -2037,6 +2037,19 @@ target_link_libraries(nr_ulsim PRIVATE
) )
target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_srssim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/srssim.c
${OPENAIR_DIR}/executables/softmodem-common.c
${NFAPI_USER_DIR}/nfapi.c
${NFAPI_USER_DIR}/gnb_ind_vars.c
${PHY_INTERFACE_DIR}/queue_t.c
)
target_link_libraries(nr_srssim PRIVATE
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc L2_NR -lz -Wl,--end-group
m pthread ITTI dl nr_ue_phy_meas physim_common
)
# these simulators do not compile: # these simulators do not compile:
# dlsim_tm7 pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim # dlsim_tm7 pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim
foreach(myExe dlsim ulsim) foreach(myExe dlsim ulsim)
...@@ -2085,7 +2098,7 @@ if (${T_TRACER}) ...@@ -2085,7 +2098,7 @@ if (${T_TRACER})
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7
ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim
syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim
nr_ulschsim ldpctest polartest smallblocktest nr_ulschsim ldpctest polartest smallblocktest nr_srssim
#all "add_library" definitions #all "add_library" definitions
ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap
params_libconfig params_libconfig
......
...@@ -44,4 +44,4 @@ RUN cmake -GNinja -DENABLE_PHYSIM_TESTS=ON \ ...@@ -44,4 +44,4 @@ RUN cmake -GNinja -DENABLE_PHYSIM_TESTS=ON \
-DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \ -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \
-DPHYSIM_CHECK_FILES="ThresholdsGracehopper.cmake" \ -DPHYSIM_CHECK_FILES="ThresholdsGracehopper.cmake" \
.. && \ .. && \
ninja ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim ninja ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim nr_srssim
...@@ -300,7 +300,7 @@ function main() { ...@@ -300,7 +300,7 @@ function main() {
SIMUS_PHY=1 SIMUS_PHY=1
CMAKE_CMD="$CMAKE_CMD -DENABLE_PHYSIM_TESTS=ON" CMAKE_CMD="$CMAKE_CMD -DENABLE_PHYSIM_TESTS=ON"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim # TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim" TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim nr_srssim"
echo_info "Will compile dlsim, ulsim, ..." echo_info "Will compile dlsim, ulsim, ..."
shift;; shift;;
-V | --vcd) -V | --vcd)
......
...@@ -138,11 +138,11 @@ ID = GNB_PHY_UL_PAYLOAD_RX_BITS ...@@ -138,11 +138,11 @@ ID = GNB_PHY_UL_PAYLOAD_RX_BITS
ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE ID = GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE
DESC = gNodeB channel estimation in the frequency domain DESC = gNodeB channel estimation in the frequency domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_f
ID = GNB_PHY_UL_TIME_CHANNEL_ESTIMATE ID = GNB_PHY_UL_TIME_CHANNEL_ESTIMATE
DESC = gNodeB channel estimation in the time domain DESC = gNodeB channel estimation in the time domain
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : int,antenna : int,port : buffer,chest_t
ID = GNB_PHY_UL_SNR_ESTIMATE ID = GNB_PHY_UL_SNR_ESTIMATE
DESC = gNodeB SNR estimation based on SRS DESC = gNodeB SNR estimation based on SRS
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
...@@ -155,6 +155,10 @@ ID = GNB_PHY_DL_OUTPUT_SIGNAL ...@@ -155,6 +155,10 @@ ID = GNB_PHY_DL_OUTPUT_SIGNAL
DESC = gNodeB output data in the freq domain for slots DESC = gNodeB output data in the freq domain for slots
GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
FORMAT = int,gNB_ID : int,frame : int,slot : int,antenna : buffer,txdata FORMAT = int,gNB_ID : int,frame : int,slot : int,antenna : buffer,txdata
ID = GNB_PHY_UL_SRS_TOA_NS
DESC = gNB ToA estimate from SRS (in ns)
GROUP = ALL:PHY:GNB
FORMAT = int,gNB_ID : int,rnti : int,frame : int,subframe : buffer,toa_ns
#MAC logs #MAC logs
ID = ENB_MAC_UE_DL_SDU ID = ENB_MAC_UE_DL_SDU
......
...@@ -360,6 +360,7 @@ float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2); ...@@ -360,6 +360,7 @@ float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2);
#define CEILIDIV(a,b) ((a+b-1)/b) #define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
#define BOUNDED_EVAL(a, b, c) (min(c, max(a, b)))
static const char *const duplex_mode_txt[] = {"FDD", "TDD"}; static const char *const duplex_mode_txt[] = {"FDD", "TDD"};
......
...@@ -32,7 +32,7 @@ The main oai binaries, which are tested by the Continuous Integration process ar ...@@ -32,7 +32,7 @@ The main oai binaries, which are tested by the Continuous Integration process ar
- The 5G gNodeB: `nr-softmodem` - The 5G gNodeB: `nr-softmodem`
- The 5G CU-UP: `nr-cuup` - The 5G CU-UP: `nr-cuup`
- The LTE PHY simulators: `dlsim` and `ulsim` - The LTE PHY simulators: `dlsim` and `ulsim`
- The 5G PHY simulators: `nr_dlschsim`, `nr_dlsim`, `nr_pbchsim`, `nr_pucchsim`, `nr_ulschsim`, `nr_ulsim`, `polartest`, `smallblocktest`, `nr _ulsim`, `ldpctest` - The 5G PHY simulators: `nr_dlschsim`, `nr_dlsim`, `nr_pbchsim`, `nr_pucchsim`, `nr_ulschsim`, `nr_ulsim`, `polartest`, `smallblocktest`, `nr _ulsim`, `ldpctest`, `nr_srssim`
Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries: Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries:
......
...@@ -89,7 +89,7 @@ be defined in order to tell cmake where the host tools have been built. ...@@ -89,7 +89,7 @@ be defined in order to tell cmake where the host tools have been built.
cd ../build-cross cd ../build-cross
cmake ../../.. -GNinja -DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build cmake ../../.. -GNinja -DCMAKE_TOOLCHAIN_FILE=../../../cmake_targets/cross-arm.cmake -DNATIVE_DIR=../build
ninja dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim ninja dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_srssim
ninja lte-softmodem nr-softmodem nr-cuup oairu lte-uesoftmodem nr-uesoftmodem ninja lte-softmodem nr-softmodem nr-cuup oairu lte-uesoftmodem nr-uesoftmodem
ninja params_libconfig coding rfsimulator ninja params_libconfig coding rfsimulator
``` ```
......
...@@ -36,6 +36,7 @@ pipelines: ...@@ -36,6 +36,7 @@ pipelines:
| | `nr_pbchsim` | Broadcast channel simulation | | | `nr_pbchsim` | Broadcast channel simulation |
| | `nr_prachsim` | PRACH simulation | | | `nr_prachsim` | PRACH simulation |
| | `nr_psbchsim` | Sidelink simulation | | | `nr_psbchsim` | Sidelink simulation |
| | `nr_srssim` | SRS simulation |
| Coding | `ldpctest`, `polartest`, `smallblocktest` | LDPC, Polar, and other FEC tests | | Coding | `ldpctest`, `polartest`, `smallblocktest` | LDPC, Polar, and other FEC tests |
## Source Locations ## Source Locations
......
...@@ -295,8 +295,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, ...@@ -295,8 +295,8 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
{ {
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config; nfapi_nr_config_request_scf_t *gNB_config = &gNB->gNB_config;
//overwrite for new NR parameters
// overwrite with new NR parameters
uint64_t rev_burst=0; uint64_t rev_burst=0;
for (int i=0; i<64; i++) for (int i=0; i<64; i++)
rev_burst |= (((position_in_burst>>(63-i))&0x01)<<i); rev_burst |= (((position_in_burst>>(63-i))&0x01)<<i);
...@@ -314,27 +314,30 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, ...@@ -314,27 +314,30 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB,
gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx; gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx;
gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx; gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx;
gNB_config->tdd_table.tdd_period.value = 0; switch (mu) {
//gNB_config->subframe_config.dl_cyclic_prefix_type.value = (fp->Ncp == NORMAL) ? NFAPI_CP_NORMAL : NFAPI_CP_EXTENDED; case 0:
gNB->gNB_config.tdd_table.tdd_period.value = 7;
if (mu==0) { fp->dl_CarrierFreq = 2600000000;
fp->dl_CarrierFreq = 2600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->ul_CarrierFreq = 2600000000;
fp->ul_CarrierFreq = 2600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->nr_band = 38;
fp->nr_band = 38; break;
// fp->threequarter_fs= 0; case 1:
} else if (mu==1) { gNB->gNB_config.tdd_table.tdd_period.value = 6;
fp->dl_CarrierFreq = 3600000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->dl_CarrierFreq = 3600000000;
fp->ul_CarrierFreq = 3600000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->ul_CarrierFreq = 3600000000;
fp->nr_band = 78; fp->nr_band = 78;
// fp->threequarter_fs= 0; break;
} else if (mu==3) { case 3:
fp->dl_CarrierFreq = 27524520000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); gNB->gNB_config.tdd_table.tdd_period.value = 3;
fp->ul_CarrierFreq = 27524520000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->dl_CarrierFreq = 27524520000;
fp->nr_band = 261; fp->ul_CarrierFreq = 27524520000;
// fp->threequarter_fs= 0; fp->nr_band = 261;
break;
default:
printf("unsupported numerology %d\n", mu);
exit(-1);
} }
fp->threequarter_fs = 0;
frequency_range_t frequency_range = get_freq_range_from_band(fp->nr_band); frequency_range_t frequency_range = get_freq_range_from_band(fp->nr_band);
int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL); int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL);
gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index);
......
...@@ -78,7 +78,7 @@ void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n ...@@ -78,7 +78,7 @@ void nr_ue_layer_mapping(const c16_t *mod_symbs, const int n_layers, const int n
\param sample_offset offset within rxdata (points to beginning of subframe) \param sample_offset offset within rxdata (points to beginning of subframe)
*/ */
int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdata, int32_t *rxdata,
int32_t *rxdataF, int32_t *rxdataF,
unsigned char symbol, unsigned char symbol,
...@@ -111,6 +111,15 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, ...@@ -111,6 +111,15 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
int first_symbol, int first_symbol,
int nsymb); int nsymb);
void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata,
c16_t **rxdataF,
const NR_DL_FRAME_PARMS *fp,
int nb_antennas,
int slot,
int slot_offsetF,
enum nr_Link linktype,
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation); void perform_symbol_rotation(NR_DL_FRAME_PARMS *fp, double f0, c16_t *symbol_rotation);
void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
......
...@@ -326,4 +326,3 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp, ...@@ -326,4 +326,3 @@ void apply_nr_rotation_TX(const NR_DL_FRAME_PARMS *fp,
} }
} }
} }
...@@ -135,7 +135,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, ...@@ -135,7 +135,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
return 0; return 0;
} }
int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int nr_slot_fep_ul(const NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdata, int32_t *rxdata,
int32_t *rxdataF, int32_t *rxdataF,
unsigned char symbol, unsigned char symbol,
...@@ -237,3 +237,27 @@ void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -237,3 +237,27 @@ void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms,
15); 15);
} }
} }
void nr_ofdm_demod_and_rx_rotation(c16_t **rxdata,
c16_t **rxdataF,
const NR_DL_FRAME_PARMS *fp,
int nb_antennas,
int slot,
int slot_offsetF,
enum nr_Link linktype,
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
{
for (int aa = 0; aa < nb_antennas; aa++) {
for (uint8_t symbol = 0; symbol < fp->symbols_per_slot; symbol++) {
if (was_symbol_used[symbol] == true) {
nr_slot_fep_ul(fp, (int32_t *)&rxdata[aa][0], (int32_t *)&rxdataF[aa][slot_offsetF], symbol, slot, 0);
apply_nr_rotation_symbol_RX(fp,
&rxdataF[aa][slot_offsetF + symbol * fp->ofdm_symbol_size],
fp->symbol_rotation[linktype],
fp->N_RB_UL,
slot,
symbol);
}
}
}
}
...@@ -36,49 +36,73 @@ ...@@ -36,49 +36,73 @@
#define I0_SKIP_DC 1 #define I0_SKIP_DC 1
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint8_t ant,
uint8_t N_ap,
uint32_t samples_per_frame,
uint16_t *ta_offset,
int16_t *ta_offset_nsec)
{ {
int timing_advance = 0; int64_t mean_val = 0;
int max_val = 0; int64_t max_val = 0;
int32_t max_idx = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { int16_t srs_toa = 0;
int temp = 0; int16_t ofdm_os_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size;
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { for (int k = 0; k < ofdm_os_size; k++) {
int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r; int64_t abs_val = 0;
int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i; for (int p_index = 0; p_index < N_ap; p_index++) {
temp += (Re*Re/2) + (Im*Im/2); abs_val += squaredMod(srs_estimated_channel_time[p_index][k]);
} }
if (temp > max_val) { mean_val += abs_val;
timing_advance = i; if (abs_val > max_val) {
max_val = temp; max_val = abs_val;
max_idx = k;
} }
} }
max_val = max_val / N_ap;
mean_val = mean_val / (N_ap * ofdm_os_size);
if (max_idx > ofdm_os_size >> 1)
max_idx = max_idx - ofdm_os_size;
// Check for detection threshold
if ((mean_val != 0) && (max_val / mean_val > NR_SRS_DETECTION_THRESHOLD)) {
srs_toa = max_idx / NR_SRS_IDFT_OVERSAMP_FACTOR;
// restrict the computation of ta_offset to antenna 0
if (ant == 0) {
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
const uint16_t bw_scaling = ofdm_symbol_size >> 7;
// do some integer rounding to improve TA accuracy
int sync_pos_rounded;
if (srs_toa > 0) {
sync_pos_rounded = srs_toa + (bw_scaling >> 1) - 1;
} else {
sync_pos_rounded = srs_toa - (bw_scaling >> 1) + 1;
}
if (timing_advance > frame_parms->ofdm_symbol_size/2) { *ta_offset = sync_pos_rounded / bw_scaling;
timing_advance = timing_advance - frame_parms->ofdm_symbol_size;
}
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
const uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 7;
// do some integer rounding to improve TA accuracy // put timing advance command in 0..63 range
int sync_pos_rounded; *ta_offset = BOUNDED_EVAL(0, *ta_offset + 31, 63);
if (timing_advance > 0) { }
sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1; *ta_offset_nsec = (max_idx * 1e9) / (NR_SRS_IDFT_OVERSAMP_FACTOR * samples_per_frame * 100);
} else { } else {
sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1; *ta_offset = 0xFFFF;
*ta_offset_nsec = 0x8000;
} }
int timing_advance_update = sync_pos_rounded / bw_scaling; LOG_D(NR_PHY,
"SRS estimatd ToA %d [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)\n",
// put timing advance command in 0..63 range srs_toa,
timing_advance_update += 31; ant,
*ta_offset,
if (timing_advance_update < 0) timing_advance_update = 0; *ta_offset_nsec,
if (timing_advance_update > 63) timing_advance_update = 63; max_val,
mean_val,
return timing_advance_update; max_idx);
} }
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) { void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
......
...@@ -59,8 +59,13 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); ...@@ -59,8 +59,13 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]); void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]);
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint8_t ant,
uint8_t N_ap,
uint32_t samples_per_frame,
uint16_t *timing_advance_offset,
int16_t *timing_advance_offset_nsec);
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
...@@ -70,21 +75,22 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, ...@@ -70,21 +75,22 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
unsigned char symbol, unsigned char symbol,
uint32_t nb_re_pusch); uint32_t nb_re_pusch);
int nr_srs_channel_estimation( int nr_srs_channel_estimation(int ant,
const PHY_VARS_gNB *gNB, int p_index,
const int frame, uint16_t ofdm_symbol_size,
const int slot, uint16_t first_carrier_offset,
const nfapi_nr_srs_pdu_t *srs_pdu, uint8_t N_symb_SRS,
const nr_srs_info_t *nr_srs_info, const nfapi_nr_srs_pdu_t *srs_pdu,
const c16_t **srs_generated_signal, const nr_srs_info_t *nr_srs_info,
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], const c16_t *srs_generated_signal,
c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], c16_t srs_received_signal[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_freq[][1 << srs_pdu->num_ant_ports] c16_t srs_received_noise[ofdm_symbol_size * N_symb_SRS],
[gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], c16_t srs_estimated_channel_freq[ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], c16_t srs_estimated_channel_time[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
c16_t srs_estimated_channel_time_shifted[][1 << srs_pdu->num_ant_ports][gNB->frame_parms.ofdm_symbol_size], c16_t srs_estimated_channel_time_shifted[NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
int16_t *snr_per_rb, uint32_t *signal_power,
int8_t *snr); uint32_t *noise_power,
int16_t *noise_power_per_rb);
void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms, void nr_freq_equalization(NR_DL_FRAME_PARMS *frame_parms,
c16_t *rxdataF_comp, c16_t *rxdataF_comp,
......
...@@ -231,6 +231,22 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, ...@@ -231,6 +231,22 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]); c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]);
void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
int frame_rx,
int slot_rx,
uint8_t nb_antennas_rx,
uint8_t N_ap,
uint8_t N_symb_SRS,
uint16_t ofdm_symbol_size,
NR_gNB_SRS_t *srs,
nr_srs_info_t *nr_srs_info,
int *srs_est,
c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
int16_t *snr_per_rb,
uint16_t *timing_advance_offset,
int16_t *timing_advance_offset_nsec);
int get_nr_prach_duration(uint8_t prach_format); int get_nr_prach_duration(uint8_t prach_format);
void free_nr_prach_entry(prach_list_t *, prach_item_t *); void free_nr_prach_entry(prach_list_t *, prach_item_t *);
......
...@@ -56,7 +56,8 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu ...@@ -56,7 +56,8 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu
srs->active = true; srs->active = true;
srs->beam_nb = 0; srs->beam_nb = 0;
if (gNB->common_vars.beam_id) { if (gNB->common_vars.beam_id) {
int bitmap = SL_to_bitmap(srs_pdu->time_start_position, 1 << srs_pdu->num_symbols); const uint8_t l0 = gNB->frame_parms.symbols_per_slot - 1 - srs_pdu->time_start_position;
int bitmap = SL_to_bitmap(l0, 1 << srs_pdu->num_symbols);
int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
srs->beam_nb = beam_index_allocation(gNB->enable_analog_das, srs->beam_nb = beam_index_allocation(gNB->enable_analog_das,
fapi_beam_idx, fapi_beam_idx,
...@@ -84,7 +85,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, ...@@ -84,7 +85,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot const uint16_t n_symbols = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot; // number of symbols until this slot
const uint8_t l0 = srs_pdu->time_start_position; // starting symbol in this slot const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_pdu->time_start_position; // starting symbol in this slot
const uint64_t symbol_offset = (n_symbols + l0) * frame_parms->ofdm_symbol_size; const uint64_t symbol_offset = (n_symbols + l0) * frame_parms->ofdm_symbol_size;
const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB; const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start * NR_NB_SC_PER_RB;
......
...@@ -168,15 +168,20 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ...@@ -168,15 +168,20 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/** \brief This function does IFFT for PUSCH /** \brief This function does IFFT for PUSCH
*/ */
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
const uint8_t slot, const NR_DL_FRAME_PARMS *frame_parms,
const NR_DL_FRAME_PARMS *frame_parms, const uint8_t n_antenna_ports,
const uint8_t n_antenna_ports, c16_t **txdataF,
c16_t **txdataF, c16_t **txdata,
c16_t **txdata, uint32_t linktype,
uint32_t linktype, bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT],
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], bool no_phase_pre_comp);
bool no_phase_pre_comp);
bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
c16_t **txdataF,
nr_phy_data_tx_t *phy_data,
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
void clean_UE_harq(PHY_VARS_NR_UE *UE); void clean_UE_harq(PHY_VARS_NR_UE *UE);
......
...@@ -1502,15 +1502,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ...@@ -1502,15 +1502,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS); stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS);
} }
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, uint8_t nr_tx_rotation_and_ofdm_mod(const uint8_t slot,
const uint8_t slot, const NR_DL_FRAME_PARMS *frame_parms,
const NR_DL_FRAME_PARMS *frame_parms, const uint8_t n_antenna_ports,
const uint8_t n_antenna_ports, c16_t **txdataF,
c16_t **txdataF, c16_t **txdata,
c16_t **txdata, uint32_t linktype,
uint32_t linktype, bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT],
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT], bool no_phase_pre_comp)
bool no_phase_pre_comp)
{ {
int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL; int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL;
......
...@@ -180,3 +180,39 @@ int32_t interference_power(int32_t *input, uint32_t length) ...@@ -180,3 +180,39 @@ int32_t interference_power(int32_t *input, uint32_t length)
return temp; return temp;
} }
// Computes transmitter energy level
double compute_tx_energy_level(c16_t **txdata, int nb_antennas, int offset, int length, int n_trials)
{
double txlev_sum = 0, atxlev[nb_antennas];
for (int aa = 0; aa < nb_antennas; aa++) {
atxlev[aa] = signal_energy((int32_t *)&txdata[aa][offset], length);
txlev_sum += atxlev[aa];
if (n_trials == 1)
printf("txlev[%d] = %f (%f dB) txlev_sum %f\n", aa, atxlev[aa], 10 * log10(atxlev[aa]), txlev_sum);
}
return txlev_sum;
}
// Computes noise variance from the input transmit energy and SNR
double compute_noise_variance(double txlev_sum,
uint16_t ofdm_symbol_size,
int N_RB,
uint8_t precod_nbr_layers,
double SNR,
int n_trials)
{
// Justification of division by precod_nbr_layers:
// When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4.
double sigma_dB = 10 * log10(txlev_sum / precod_nbr_layers * ((double)ofdm_symbol_size / (12 * N_RB))) - SNR;
double sigma = pow(10, sigma_dB / 10);
if (n_trials == 1)
printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",
sigma,
sigma_dB,
10 * log10(txlev_sum),
(double)(double)ofdm_symbol_size / (12 * N_RB));
return sigma;
}
...@@ -927,6 +927,14 @@ double signal_energy_fp(double *s_re[2], double *s_im[2], uint32_t nb_antennas, ...@@ -927,6 +927,14 @@ double signal_energy_fp(double *s_re[2], double *s_im[2], uint32_t nb_antennas,
*/ */
double signal_energy_fp2(struct complexd *s, uint32_t length); double signal_energy_fp2(struct complexd *s, uint32_t length);
double compute_tx_energy_level(c16_t **txdata, int nb_antennas, int offset, int length, int n_trials);
double compute_noise_variance(double txlev_sum,
uint16_t ofdm_symbol_size,
int N_RB,
uint8_t precod_nbr_layers,
double SNR,
int n_trials);
int32_t iSqrt(int32_t value); int32_t iSqrt(int32_t value);
uint8_t log2_approx(uint32_t); uint8_t log2_approx(uint32_t);
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#define MAX_NUM_RU_PER_gNB 8 #define MAX_NUM_RU_PER_gNB 8
#define MAX_PUCCH0_NID 8 #define MAX_PUCCH0_NID 8
#define NR_SRS_IDFT_OVERSAMP_FACTOR 2
#define NR_SRS_DETECTION_THRESHOLD 10
typedef struct { typedef struct {
int nb_id; int nb_id;
......
...@@ -372,7 +372,8 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -372,7 +372,8 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms,
nr_srs_info_t *nr_srs_info, nr_srs_info_t *nr_srs_info,
int16_t amp, int16_t amp,
frame_t frame_number, frame_t frame_number,
slot_t slot_number); slot_t slot_number,
uint8_t nb_antennas);
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
const csi_mapping_parms_t *phy_csi_parms, const csi_mapping_parms_t *phy_csi_parms,
const int16_t amp, const int16_t amp,
......
...@@ -146,11 +146,12 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -146,11 +146,12 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms,
nr_srs_info_t *nr_srs_info, nr_srs_info_t *nr_srs_info,
int16_t amp, int16_t amp,
frame_t frame_number, frame_t frame_number,
slot_t slot_number) slot_t slot_number,
uint8_t nb_antennas)
{ {
uint8_t K_TC = 2 << nr_srs_info->comb_size; uint8_t K_TC = 2 << nr_srs_info->comb_size;
/* Number of antenna ports (M) can't be higher than number of physical antennas (N): M <= N */ /* Number of antenna ports (M) can't be higher than number of physical antennas (N): M <= N */
int N_ap = nr_srs_info->n_srs_ports > frame_parms->nb_antennas_tx ? frame_parms->nb_antennas_tx : nr_srs_info->n_srs_ports; int N_ap = nr_srs_info->n_srs_ports > nb_antennas ? nb_antennas : nr_srs_info->n_srs_ports;
uint8_t l0 = frame_parms->symbols_per_slot - 1 - nr_srs_info->l_offset; // Starting symbol position in the time domain uint8_t l0 = frame_parms->symbols_per_slot - 1 - nr_srs_info->l_offset; // Starting symbol position in the time domain
uint8_t n_SRS_cs_max = srs_max_number_cs[nr_srs_info->comb_size]; uint8_t n_SRS_cs_max = srs_max_number_cs[nr_srs_info->comb_size];
int m_SRS_b = get_m_srs(nr_srs_info->C_SRS, nr_srs_info->B_SRS); // Number of resource blocks int m_SRS_b = get_m_srs(nr_srs_info->C_SRS, nr_srs_info->B_SRS); // Number of resource blocks
...@@ -180,6 +181,11 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms, ...@@ -180,6 +181,11 @@ bool generate_srs_nr(const NR_DL_FRAME_PARMS *frame_parms,
LOG_I(NR_PHY,"M_sc_b_SRS = %i\n", M_sc_b_SRS); LOG_I(NR_PHY,"M_sc_b_SRS = %i\n", M_sc_b_SRS);
#endif #endif
AssertFatal(l0 + nr_srs_info->N_symb_SRS - 1 < frame_parms->symbols_per_slot,
"last symbol index %d should be < %d\n",
l0 + nr_srs_info->N_symb_SRS,
frame_parms->symbols_per_slot - 1);
// Validation of SRS config parameters // Validation of SRS config parameters
if (nr_srs_info->R == 0) { if (nr_srs_info->R == 0) {
......
...@@ -199,8 +199,8 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) ...@@ -199,8 +199,8 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
switch (mu) switch (mu)
{ {
case 0: case 0:
pc->num_dl_slots = 3; pc->num_dl_slots = 7;
pc->num_ul_slots = 1; pc->num_ul_slots = 2;
break; break;
case 1: case 1:
...@@ -209,8 +209,8 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) ...@@ -209,8 +209,8 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
break; break;
case 3: case 3:
pc->num_dl_slots = 27; pc->num_dl_slots = 7;
pc->num_ul_slots = 12; pc->num_ul_slots = 2;
break; break;
default: default:
...@@ -226,7 +226,7 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu) ...@@ -226,7 +226,7 @@ void do_tdd_config_sim(PHY_VARS_gNB *gNB, int mu)
pc->tdd_slot_bitmap[i].num_dl_symbols = 6; pc->tdd_slot_bitmap[i].num_dl_symbols = 6;
pc->tdd_slot_bitmap[i].num_ul_symbols = 4; pc->tdd_slot_bitmap[i].num_ul_symbols = 4;
} }
for (int i = pc->num_ul_slots; i < fs.numb_slots_period; i++) { for (int i = fs.numb_slots_period - pc->num_ul_slots; i < fs.numb_slots_period; i++) {
pc->tdd_slot_bitmap[i].slot_type = TDD_NR_UPLINK_SLOT; pc->tdd_slot_bitmap[i].slot_type = TDD_NR_UPLINK_SLOT;
pc->tdd_slot_bitmap[i].num_dl_symbols = 0; pc->tdd_slot_bitmap[i].num_dl_symbols = 0;
pc->tdd_slot_bitmap[i].num_ul_symbols = 0; pc->tdd_slot_bitmap[i].num_ul_symbols = 0;
......
This diff is collapsed.
...@@ -304,7 +304,7 @@ static void configure_srs_info(fapi_nr_ul_config_srs_pdu *srs_config_pdu, nr_srs ...@@ -304,7 +304,7 @@ static void configure_srs_info(fapi_nr_ul_config_srs_pdu *srs_config_pdu, nr_srs
* send srs according to current configuration * send srs according to current configuration
* *
*********************************************************************/ *********************************************************************/
static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
c16_t **txdataF, c16_t **txdataF,
nr_phy_data_tx_t *phy_data, nr_phy_data_tx_t *phy_data,
...@@ -314,12 +314,13 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, ...@@ -314,12 +314,13 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
return false; return false;
} }
NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms);
fapi_nr_ul_config_srs_pdu *srs_config_pdu = &phy_data->srs_vars.srs_config_pdu; fapi_nr_ul_config_srs_pdu *srs_config_pdu = &phy_data->srs_vars.srs_config_pdu;
int first_srs_symbol = ue->frame_parms.symbols_per_slot - 1 - srs_config_pdu->time_start_position; const uint8_t l0 = frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position;
// Num consecutive SRS symbols according to 38.211 6.4.1.4.1 // Num consecutive SRS symbols according to 38.211 6.4.1.4.1
int num_srs_symbols[] = {1, 2, 4, 8, 12}; int num_srs_symbols[] = {1, 2, 4, 8, 12};
int last_srs_symbol = first_srs_symbol + num_srs_symbols[srs_config_pdu->num_symbols] - 1; int last_srs_symbol = l0 + num_srs_symbols[srs_config_pdu->num_symbols] - 1;
for (int i = first_srs_symbol; i <= last_srs_symbol; i++) { for (int i = l0; i <= last_srs_symbol; i++) {
was_symbol_used[i] = true; was_symbol_used[i] = true;
} }
...@@ -351,8 +352,7 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, ...@@ -351,8 +352,7 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
#endif #endif
configure_srs_info(srs_config_pdu, ue->nr_srs_info); configure_srs_info(srs_config_pdu, ue->nr_srs_info);
NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms); uint16_t symbol_offset = l0 * frame_parms->ofdm_symbol_size;
uint16_t symbol_offset = (frame_parms->symbols_per_slot - 1 - srs_config_pdu->time_start_position)*frame_parms->ofdm_symbol_size;
bool generated = generate_srs_nr(frame_parms, bool generated = generate_srs_nr(frame_parms,
txdataF, txdataF,
symbol_offset, symbol_offset,
...@@ -360,7 +360,8 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, ...@@ -360,7 +360,8 @@ static bool ue_srs_procedures_nr(PHY_VARS_NR_UE *ue,
ue->nr_srs_info, ue->nr_srs_info,
AMP, AMP,
proc->frame_tx, proc->frame_tx,
proc->nr_slot_tx); proc->nr_slot_tx,
frame_parms->nb_antennas_tx);
return generated; return generated;
} }
...@@ -400,15 +401,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n ...@@ -400,15 +401,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
const NR_UE_PRACH *prach_var = ue->prach_vars[proc->gNB_id]; const NR_UE_PRACH *prach_var = ue->prach_vars[proc->gNB_id];
if (!prach_var->active) { if (!prach_var->active) {
start_meas_nr_ue_phy(ue, OFDM_MOD_STATS); start_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
nr_ue_pusch_common_procedures(ue, nr_tx_rotation_and_ofdm_mod(proc->nr_slot_tx,
proc->nr_slot_tx, &ue->frame_parms,
&ue->frame_parms, ue->frame_parms.nb_antennas_tx,
ue->frame_parms.nb_antennas_tx, (c16_t **)txdataF,
(c16_t **)txdataF, txp,
txp, link_type_ul,
link_type_ul, was_symbol_used,
was_symbol_used, ue->no_phase_pre_comp);
ue->no_phase_pre_comp);
stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS); stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
} }
......
...@@ -315,15 +315,14 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc ...@@ -315,15 +315,14 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
was_symbol_used[i] = true; was_symbol_used[i] = true;
if (tx_action) { if (tx_action) {
LOG_D(NR_PHY, "Sending Uplink data \n"); LOG_D(NR_PHY, "Sending Uplink data \n");
nr_ue_pusch_common_procedures(ue, nr_tx_rotation_and_ofdm_mod(proc->nr_slot_tx,
proc->nr_slot_tx, fp,
fp, fp->nb_antennas_tx,
fp->nb_antennas_tx, txdataF,
txdataF, txp,
txp, link_type_sl,
link_type_sl, was_symbol_used,
was_symbol_used, ue->no_phase_pre_comp);
ue->no_phase_pre_comp);
} }
LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
......
...@@ -324,7 +324,7 @@ int main(int argc, char **argv) ...@@ -324,7 +324,7 @@ int main(int argc, char **argv)
setbuf(stdout, NULL); setbuf(stdout, NULL);
int c; int c;
int i,aa;//,l; int i,aa;//,l;
double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0; double SNR, snr0 = -2.0, snr1 = 2.0;
uint8_t snr1set=0; uint8_t snr1set=0;
double effRate; double effRate;
//float psnr; //float psnr;
...@@ -1172,15 +1172,12 @@ int main(int argc, char **argv) ...@@ -1172,15 +1172,12 @@ int main(int argc, char **argv)
} }
} }
int txlev[n_tx]; // Compute transmitter energy level
int txlev_sum = 0;
int l_ofdm = 6; int l_ofdm = 6;
for (aa=0; aa<n_tx; aa++) { int symbol_offset = slot_offset + l_ofdm * frame_parms->ofdm_symbol_size + (l_ofdm - 1) * frame_parms->nb_prefix_samples
txlev[aa] = signal_energy((int32_t *)&txdata[aa][slot_offset +l_ofdm*frame_parms->ofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + frame_parms->nb_prefix_samples0;
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); int symbol_length = frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples;
txlev_sum += txlev[aa]; double txlev_sum = compute_tx_energy_level(txdata, n_tx, symbol_offset, symbol_length, n_trials);
if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum);
}
for (i = 0; i < slot_length; i++) { for (i = 0; i < slot_length; i++) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
...@@ -1189,11 +1186,11 @@ int main(int argc, char **argv) ...@@ -1189,11 +1186,11 @@ int main(int argc, char **argv)
} }
} }
double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
//Compute AWGN variance
sigma2_dB = 10 * log10((double)txlev_sum * ((double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize))) - SNR; // Estimate noise power from the transmitter level and SNR
sigma2 = pow(10, sigma2_dB/10); double sigma2 =
if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*pdsch_pdu_rel15->rbSize)); compute_noise_variance(txlev_sum, UE->frame_parms.ofdm_symbol_size, pdsch_pdu_rel15->rbSize, 1, SNR, n_trials);
for (aa = 0; aa < n_rx; aa++) { for (aa = 0; aa < n_rx; aa++) {
bzero(r_re[aa], slot_length * sizeof(double)); bzero(r_re[aa], slot_length * sizeof(double));
......
...@@ -131,7 +131,7 @@ int main(int argc, char **argv){ ...@@ -131,7 +131,7 @@ int main(int argc, char **argv){
sigaction(SIGINT, &sigint_action, &oldaction); sigaction(SIGINT, &sigint_action, &oldaction);
get_softmodem_params()->sl_mode = 0; get_softmodem_params()->sl_mode = 0;
double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; double SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw; double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw;
int i, l, aa, aarx, trial, n_frames = 1, rx_prach_start; //, ntrials=1; int i, l, aa, aarx, trial, n_frames = 1, rx_prach_start; //, ntrials=1;
c16_t **txdata; c16_t **txdata;
...@@ -728,14 +728,7 @@ int main(int argc, char **argv){ ...@@ -728,14 +728,7 @@ int main(int argc, char **argv){
for (trial = 0; trial < n_frames && !stop; trial++) { for (trial = 0; trial < n_frames && !stop; trial++) {
if (input_fd == NULL) { if (input_fd == NULL) {
sigma2_dB = 10*log10((double)tx_lev) - SNR - 10*log10(N_RB_UL*12/N_ZC); double sigma2 = compute_noise_variance(tx_lev, N_ZC, N_RB_UL, 1, SNR, n_frames);
if (n_frames==1)
printf("sigma2_dB %f (SNR %f dB) tx_lev_dB %f\n",sigma2_dB,SNR,10*log10((double)tx_lev));
//AWGN
sigma2 = pow(10,sigma2_dB/10);
// printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB);
if (awgn_flag == 0) { if (awgn_flag == 0) {
multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0); multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0);
......
...@@ -96,7 +96,7 @@ int main(int argc, char **argv) ...@@ -96,7 +96,7 @@ int main(int argc, char **argv)
sigaction(SIGINT, &sigint_action, &oldaction); sigaction(SIGINT, &sigint_action, &oldaction);
int i;//,l; int i;//,l;
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double SNR, snr0 = -2.0, snr1 = 2.0;
double cfo=0; double cfo=0;
uint8_t snr1set=0; uint8_t snr1set=0;
double **s_re,**s_im,**r_re,**r_im; double **s_re,**s_im,**r_re,**r_im;
...@@ -566,15 +566,16 @@ int main(int argc, char **argv) ...@@ -566,15 +566,16 @@ int main(int argc, char **argv)
// SNR Computation // SNR Computation
// standard says: SNR = S / N, where S is the total signal energy, N is the noise energy in the transmission bandwidth (i.e. N_RB_DL resource blocks) // standard says: SNR = S / N, where S is the total signal energy, N is the noise energy in the transmission bandwidth (i.e. N_RB_DL resource blocks)
// txlev = S. // txlev = S.
int txlev = signal_energy((int32_t *)&txdataF[0][startingSymbolIndex*frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size);
// Compute transmitter energy level
int symbol_offset = startingSymbolIndex * frame_parms->ofdm_symbol_size;
int symbol_length = frame_parms->ofdm_symbol_size;
double txlev = compute_tx_energy_level(txdataF, 1, symbol_offset, symbol_length, n_trials);
// sigma2 is variance per dimension, so N/(N_RB*12) // sigma2 is variance per dimension, so N/(N_RB*12)
// so, sigma2 = N/(N_RB_DL*12) => (S/SNR)/(N_RB*12) // so, sigma2 = N/(N_RB_DL*12) => (S/SNR)/(N_RB*12)
int N_RB = (format == 0 || format == 1) ? 1 : nrofPRB; int N_RB = (format == 0 || format == 1) ? 1 : nrofPRB;
sigma2_dB = 10*log10(txlev*(N_RB_DL/N_RB))-SNR; double sigma2 = compute_noise_variance(txlev, N_RB_DL * 12, N_RB, 1, SNR, n_trials);
sigma2 = pow(10.0,sigma2_dB/10.0);
if (n_trials==1) printf("txlev %d (%f dB), offset %d, sigma2 %f ( %f dB)\n",txlev,10*log10(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size,sigma2,sigma2_dB);
for (int symb=0; symb<gNB->frame_parms.symbols_per_slot;symb++) { for (int symb=0; symb<gNB->frame_parms.symbols_per_slot;symb++) {
if (symb<startingSymbolIndex || symb >= startingSymbolIndex+nrofSymbols) { if (symb<startingSymbolIndex || symb >= startingSymbolIndex+nrofSymbols) {
...@@ -648,7 +649,16 @@ int main(int argc, char **argv) ...@@ -648,7 +649,16 @@ int main(int argc, char **argv)
gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot, rb_mask_ul); gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot, rb_mask_ul);
start_meas(&gNB->phy_proc_rx); start_meas(&gNB->phy_proc_rx);
if (n_trials==1) printf("noise rxlev %d (%d dB), rxlev pucch %d dB sigma2 %f dB, SNR %f, TX %f, I0 (pucch) %d, I0 (avg) %d\n",rxlev,dB_fixed(rxlev),dB_fixed(rxlev_pucch),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12),gNB->measurements.n0_subband_power_tot_dB[startingPRB],gNB->measurements.n0_subband_power_avg_dB); if (n_trials == 1)
printf("noise rxlev %d (%d dB), rxlev pucch %d dB sigma2 %f dB, SNR %f, TX %f, I0 (pucch) %d, I0 (avg) %d\n",
rxlev,
dB_fixed(rxlev),
dB_fixed(rxlev_pucch),
10 * log10(sigma2),
SNR,
10 * log10((double)txlev * UE->frame_parms.ofdm_symbol_size / 12),
gNB->measurements.n0_subband_power_tot_dB[startingPRB],
gNB->measurements.n0_subband_power_avg_dB);
if(format==0){ if(format==0){
nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu;
nfapi_nr_pucch_pdu_t pucch_pdu; nfapi_nr_pucch_pdu_t pucch_pdu;
......
This diff is collapsed.
...@@ -281,7 +281,6 @@ int main(int argc, char *argv[]) ...@@ -281,7 +281,6 @@ int main(int argc, char *argv[])
char *filename_csv = NULL; char *filename_csv = NULL;
int i; int i;
double SNR, snr0 = -2.0, snr1 = 2.0; double SNR, snr0 = -2.0, snr1 = 2.0;
double sigma, sigma_dB;
double snr_step = .2; double snr_step = .2;
uint8_t snr1set = 0; uint8_t snr1set = 0;
int slot = 8, frame = 1; int slot = 8, frame = 1;
...@@ -308,7 +307,7 @@ int main(int argc, char *argv[]) ...@@ -308,7 +307,7 @@ int main(int argc, char *argv[])
int Imcs = 9; int Imcs = 9;
uint8_t precod_nbr_layers = 1; uint8_t precod_nbr_layers = 1;
int tx_offset; int tx_offset;
int32_t txlev_sum = 0, atxlev[4]; double txlev_sum = 0;
int start_rb = 0; int start_rb = 0;
int UE_id = 0; int UE_id = 0;
int print_perf = 0; int print_perf = 0;
...@@ -1273,7 +1272,7 @@ int main(int argc, char *argv[]) ...@@ -1273,7 +1272,7 @@ int main(int argc, char *argv[])
srs_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing; srs_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing;
srs_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0; srs_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0;
srs_pdu->sequence_id = 40; srs_pdu->sequence_id = 40;
srs_pdu->time_start_position = gNB->frame_parms.symbols_per_slot - 1; srs_pdu->time_start_position = 0;
srs_pdu->config_index = rrc_get_max_nr_csrs(srs_pdu->bwp_size, srs_pdu->bandwidth_index); srs_pdu->config_index = rrc_get_max_nr_csrs(srs_pdu->bwp_size, srs_pdu->bandwidth_index);
srs_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic; srs_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic;
srs_pdu->t_srs = 1; srs_pdu->t_srs = 1;
...@@ -1371,6 +1370,7 @@ int main(int argc, char *argv[]) ...@@ -1371,6 +1370,7 @@ int main(int argc, char *argv[])
srs_config_pdu->sequence_id = 40; srs_config_pdu->sequence_id = 40;
srs_config_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic; srs_config_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic;
srs_config_pdu->t_srs = 1; srs_config_pdu->t_srs = 1;
srs_config_pdu->time_start_position = 0;
} }
for (int i = 0; i < (TBS / 8); i++) for (int i = 0; i < (TBS / 8); i++)
...@@ -1400,36 +1400,22 @@ int main(int argc, char *argv[]) ...@@ -1400,36 +1400,22 @@ int main(int argc, char *argv[])
} }
/////////// ///////////
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// Compute transmitter energy level
tx_offset = get_samples_slot_timestamp(&gNB->frame_parms, slot); tx_offset = get_samples_slot_timestamp(&gNB->frame_parms, slot);
txlev_sum = 0; int symbol_offset = tx_offset + 5 * gNB->frame_parms.ofdm_symbol_size + 4 * gNB->frame_parms.nb_prefix_samples
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { + gNB->frame_parms.nb_prefix_samples0;
atxlev[aa] = int symbol_length = gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.nb_prefix_samples;
signal_energy((int32_t *)&UE->common_vars txlev_sum = compute_tx_energy_level(UE->common_vars.txData,
.txData[aa][tx_offset + 5 * gNB->frame_parms.ofdm_symbol_size UE->frame_parms.nb_antennas_tx,
+ 4 * gNB->frame_parms.nb_prefix_samples + gNB->frame_parms.nb_prefix_samples0], symbol_offset,
gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.nb_prefix_samples); symbol_length,
n_trials);
txlev_sum += atxlev[aa];
if (n_trials == 1)
printf("txlev[%d] = %d (%f dB) txlev_sum %d\n", aa, atxlev[aa], 10 * log10((double)atxlev[aa]), txlev_sum);
}
} else } else
n_trials = 1; n_trials = 1;
if (input_fd == NULL) { if (input_fd == NULL) {
// Justification of division by precod_nbr_layers: double sigma =
// When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4. compute_noise_variance(txlev_sum, gNB->frame_parms.ofdm_symbol_size, nb_rb, precod_nbr_layers, SNR, n_trials);
sigma_dB =
10 * log10((double)txlev_sum / precod_nbr_layers * ((double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb))) - SNR;
sigma = pow(10, sigma_dB / 10);
if (n_trials == 1)
printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n",
sigma,
sigma_dB,
10 * log10((double)txlev_sum),
(double)(double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb));
for (i = 0; i < slot_length; i++) { for (i = 0; i < slot_length; i++) {
for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) {
...@@ -1460,26 +1446,20 @@ int main(int argc, char *argv[]) ...@@ -1460,26 +1446,20 @@ int main(int argc, char *argv[])
UL_INFO.crc_ind.number_crcs = 0; UL_INFO.crc_ind.number_crcs = 0;
UL_INFO.srs_ind.number_of_pdus = 0; UL_INFO.srs_ind.number_of_pdus = 0;
for(uint8_t symbol = 0; symbol < (gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); symbol++) { //----------- OFDM Demodulation and RX rotation--------------------------
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) bool was_symbol_used[14] = {0};
nr_slot_fep_ul(&gNB->frame_parms,
(int32_t *)rxdata[aa],
(int32_t *)gNB->common_vars.rxdataF[0][aa],
symbol,
slot,
0);
}
int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size;
for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { for (int i = 0; i < 14; i++) {
const unsigned int max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14; was_symbol_used[i] = true;
for (int sym = 0; sym < max_symb; sym++)
apply_nr_rotation_symbol_RX(&gNB->frame_parms,
gNB->common_vars.rxdataF[0][aa] + offset + sym * gNB->frame_parms.ofdm_symbol_size,
gNB->frame_parms.symbol_rotation[1],
gNB->frame_parms.N_RB_UL,
slot,
sym);
} }
nr_ofdm_demod_and_rx_rotation(rxdata,
gNB->common_vars.rxdataF[0],
&gNB->frame_parms,
gNB->frame_parms.nb_antennas_rx,
slot,
offset,
link_type_ul,
was_symbol_used);
ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO); ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO);
......
...@@ -68,7 +68,7 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des ...@@ -68,7 +68,7 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des
#ifdef DEBUG_CH #ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) { for (int l = 0; l<(int)desc->channel_length; l++) {
printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y); printf("%p (%f,%f) ",desc->ch[0],desc->ch[0][l].x,desc->ch[0][l].y);
} }
...@@ -168,7 +168,7 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des ...@@ -168,7 +168,7 @@ void __attribute__ ((no_sanitize_address)) multipath_channel(channel_desc_t *des
} }
#ifdef DEBUG_CH #ifdef DEBUG_CH
for (l = 0; l<(int)desc->channel_length; l++) { for (int l = 0; l<(int)desc->channel_length; l++) {
printf("ch[%i] = (%f, %f)\n", l, desc->ch[0][l].r, desc->ch[0][l].i); printf("ch[%i] = (%f, %f)\n", l, desc->ch[0][l].r, desc->ch[0][l].i);
} }
#endif #endif
......
...@@ -341,6 +341,27 @@ add_physim_test(physim.5g.nr_prachsim.test8 "15kHz SCS, 25 PRBs" nr_prachsim -a ...@@ -341,6 +341,27 @@ add_physim_test(physim.5g.nr_prachsim.test8 "15kHz SCS, 25 PRBs" nr_prachsim -a
add_physim_test(physim.5g.nr_psbchsim.test1 "SLSS Search" nr_psbchsim -I) add_physim_test(physim.5g.nr_psbchsim.test1 "SLSS Search" nr_psbchsim -I)
add_physim_test(physim.5g.nr_psbchsim.test2 "PSBCH TxRx" nr_psbchsim -n 30) add_physim_test(physim.5g.nr_psbchsim.test2 "PSBCH TxRx" nr_psbchsim -n 30)
####################################################################################
###### nr_srssim unit test ######
####################################################################################
add_physim_test(physim.5g.nr_srssim.test1 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 2" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 24)
add_physim_test(physim.5g.nr_srssim.test2 "SRS: 30KHz SCS, 106 PRBs, ToA 15, Combsize 2, Threequarter sampling" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 15 -k)
add_physim_test(physim.5g.nr_srssim.test3 "SRS: 30KHz SCS, 217 PRBs, ToA 8, Combsize 2" nr_srssim -n300 -R217 -s0 -S5 -y2 -z2 -d 8)
add_physim_test(physim.5g.nr_srssim.test4 "SRS: 30KHz SCS, 273 PRBs, TOA 30, Combsize 2" nr_srssim -n300 -R273 -s0 -S5 -y2 -z2 -d 30)
add_physim_test(physim.5g.nr_srssim.test5 "SRS: 30KHz SCS, 106 PRBs, ToA 16, Combsize 2, Cyclic shift 3" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 16 -i 1)
add_physim_test(physim.5g.nr_srssim.test6 "SRS: 30KHz SCS, 106 PRBs, ToA 23, Combsize 2, Comb offset 1" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 23 -f 1)
add_physim_test(physim.5g.nr_srssim.test7 "SRS: 30KHz SCS, 106 PRBs, ToA 8, Combsize 2, Symbol start 9" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 8 -a 9)
add_physim_test(physim.5g.nr_srssim.test8 "SRS: 120KHz SCS, 32 PRBs, ToA 19, Combsize 2" nr_srssim -n300 -R32 -s0 -S5 -y2 -z2 -d 19 -u 3)
add_physim_test(physim.5g.nr_srssim.test9 "SRS: 30KHz SCS, 106 PRBs, ToA 11, Combsize 4" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 11 -e 1)
add_physim_test(physim.5g.nr_srssim.test10 "SRS: 30KHz SCS, 106 PRBs, ToA 7, Combsize 4, Comb offset 1" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 7 -e 1 -f 1)
add_physim_test(physim.5g.nr_srssim.test11 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 2, SRS symbols 2, SRS start symbol 8" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 24 -b 2 -a 8)
add_physim_test(physim.5g.nr_srssim.test12 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 2, SRS symbols 4, SRS start symbol 8" nr_srssim -n300 -R106 -s0 -S5 -y2 -z2 -d 24 -b 4 -a 8)
add_physim_test(physim.5g.nr_srssim.test13 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 4, SRS symbols 2, SRS start symbol 8" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 24 -b 2 -e1 -a 8)
add_physim_test(physim.5g.nr_srssim.test14 "SRS: 30KHz SCS, 106 PRBs, ToA 24, Combsize 4, SRS symbols 4, SRS start symbol 8" nr_srssim -n300 -R106 -s5 -S10 -y2 -z2 -d 24 -b 4 -e1 -a 8)
add_physim_test(physim.5g.nr_srssim.test15 "SRS: 30KHz SCS, 217 PRBs, ToA 8, Combsize 2, SRS symbols 4, SRS start symbol 8" nr_srssim -n300 -R217 -s0 -S5 -y2 -z2 -d 8 -b 4 -a 8)
add_physim_test(physim.5g.nr_srssim.test16 "SRS: 30KHz SCS, 106 PRBs, SNR 2 dB to 30 dB in steps of 5 dB, ToA 24, Combsize 2" nr_srssim -n300 -R106 -s2 -S30 -y2 -z2 -d 24)
#################################################################################### ####################################################################################
###### offload-specific tests ###### ###### offload-specific tests ######
#################################################################################### ####################################################################################
......
...@@ -428,7 +428,7 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac, ...@@ -428,7 +428,7 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac,
srs_pdu->num_ant_ports = srs_resource->nrofSRS_Ports; srs_pdu->num_ant_ports = srs_resource->nrofSRS_Ports;
srs_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols; srs_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols;
srs_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor; srs_pdu->num_repetitions = srs_resource->resourceMapping.repetitionFactor;
srs_pdu->time_start_position = NR_NUMBER_OF_SYMBOLS_PER_SLOT - 1 - srs_resource->resourceMapping.startPosition; srs_pdu->time_start_position = srs_resource->resourceMapping.startPosition;
srs_pdu->config_index = srs_resource->freqHopping.c_SRS; srs_pdu->config_index = srs_resource->freqHopping.c_SRS;
srs_pdu->sequence_id = srs_resource->sequenceId; srs_pdu->sequence_id = srs_resource->sequenceId;
srs_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS; srs_pdu->bandwidth_index = srs_resource->freqHopping.b_SRS;
...@@ -479,7 +479,8 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac, ...@@ -479,7 +479,8 @@ static void nr_configure_srs(gNB_MAC_INST *nrmac,
AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n"); AssertFatal(beam.idx >= 0, "Cannot allocate SRS in any available beam\n");
uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE]; uint16_t *vrb_map_UL = &nrmac->common_channels[CC_id].vrb_map_UL[beam.idx][buffer_index * MAX_BWP_SIZE];
uint16_t num = 1 << srs_pdu->num_symbols; // 0,1,2 means 1,2,4 symbols, see 222.10.04 table 3-105 uint16_t num = 1 << srs_pdu->num_symbols; // 0,1,2 means 1,2,4 symbols, see 222.10.04 table 3-105
uint16_t mask = SL_to_bitmap(srs_pdu->time_start_position, num); const uint8_t l0 = NR_NUMBER_OF_SYMBOLS_PER_SLOT - 1 - srs_pdu->time_start_position;
uint16_t mask = SL_to_bitmap(l0, num);
DevAssert(mask != 0); DevAssert(mask != 0);
for (int i = 0; i < srs_pdu->bwp_size; ++i) { for (int i = 0; i < srs_pdu->bwp_size; ++i) {
int rb = i + srs_pdu->bwp_start; int rb = i + srs_pdu->bwp_start;
......
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