Merge remote-tracking branch 'origin/pucch2-delay-compensation' into integration_2025_w03 (!3034)
Delay compensation for PUCCH2 - Implementation of delay compensation for PUCCH2, which minimizes for exampe logs "reported RSRP index XXX invalid" - Adding a test to the CI to perform the delay compensation in PUCCH2 - Refactor code to use c16_t data type in PUCCH decoder
This commit is contained in:
@@ -318,7 +318,8 @@
|
||||
(Test25: Format 2 11-bit 2/273 PRB),
|
||||
(Test26: Format 2 12-bit 8/273 PRB),
|
||||
(Test27: Format 2 19-bit 8/273 PRB),
|
||||
(Test28: Format 2 64-bit 16/273 PRB)</desc>
|
||||
(Test28: Format 2 64-bit 16/273 PRB),
|
||||
(Test29: Format 2 64-bit 16/273 PRB Delay 2us)</desc>
|
||||
<main_exec>nr_pucchsim</main_exec>
|
||||
<main_exec_args>-R 106 -i 1 -P 0 -b 1 -s-2 -n1000
|
||||
-R 106 -i 1 -P 0 -b 2 -s-2 -n1000
|
||||
@@ -347,8 +348,9 @@
|
||||
-R 273 -z8 -i 1 -P 2 -b 11 -s6 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -q8 -b 12 -s-3 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -q8 -b 19 -s-3 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -q16 -b 64 -s-3 -n1000</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 test22 test23 test24 test25 test26 test27 test28</tags>
|
||||
-R 273 -z8 -i 1 -P 2 -q16 -b 64 -s-3 -n1000
|
||||
-R 273 -z8 -i 1 -P 2 -q16 -b 64 -s-3 -d 2 -n1000</main_exec_args>
|
||||
<tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 test22 test23 test24 test25 test26 test27 test28 test29</tags>
|
||||
<search_expr_true>PUCCH test OK</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
|
||||
@@ -651,6 +651,10 @@ void log_dump(int component,
|
||||
wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL);
|
||||
break;
|
||||
|
||||
case LOG_DUMP_C16:
|
||||
wbuf = malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL);
|
||||
break;
|
||||
|
||||
case LOG_DUMP_CHAR:
|
||||
default:
|
||||
wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL);
|
||||
@@ -669,6 +673,21 @@ void log_dump(int component,
|
||||
pos = pos + sprintf(wbuf+pos,"%04.4lf ", (double)((double *)buffer)[i]);
|
||||
break;
|
||||
|
||||
case LOG_DUMP_I16: {
|
||||
int16_t *tmp = ((int16_t *)buffer) + i;
|
||||
pos = pos + sprintf(wbuf + pos, "%d, ", *tmp);
|
||||
} break;
|
||||
|
||||
case LOG_DUMP_C16: {
|
||||
int16_t *tmp = ((int16_t *)buffer) + i * 2;
|
||||
pos = pos + sprintf(wbuf + pos, "(%d,%d), ", *tmp, *(tmp + 1));
|
||||
} break;
|
||||
|
||||
case LOG_DUMP_C32: {
|
||||
int32_t *tmp = ((int32_t *)buffer) + i * 2;
|
||||
pos = pos + sprintf(wbuf + pos, "(%d,%d), ", *tmp, *(tmp + 1));
|
||||
} break;
|
||||
|
||||
case LOG_DUMP_CHAR:
|
||||
default:
|
||||
pos = pos + sprintf(wbuf+pos,"%02x ", (unsigned char)((unsigned char *)buffer)[i]);
|
||||
|
||||
@@ -335,6 +335,9 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
* @{*/
|
||||
#define LOG_DUMP_CHAR 0
|
||||
#define LOG_DUMP_DOUBLE 1
|
||||
#define LOG_DUMP_I16 2
|
||||
#define LOG_DUMP_C16 3
|
||||
#define LOG_DUMP_C32 4
|
||||
// debugging macros
|
||||
#define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
|
||||
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
|
||||
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
|
||||
init_delay_table(128, MAX_DELAY_COMP, 128, fp->delay_table128);
|
||||
|
||||
gNB->bad_pucch = 0;
|
||||
if (gNB->TX_AMP == 0)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -217,6 +217,8 @@ struct NR_DL_FRAME_PARMS {
|
||||
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
|
||||
/// Table used to apply the delay compensation in DL/UL
|
||||
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE];
|
||||
/// Table used to apply the delay compensation in PUCCH2
|
||||
c16_t delay_table128[2 * MAX_DELAY_COMP + 1][128];
|
||||
/// SRS configuration from TS 38.331 RRC
|
||||
SRS_NR srs_nr;
|
||||
/// Power used by SSB in order to estimate signal strength and path loss
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#define USE_128BIT
|
||||
#endif
|
||||
|
||||
#define PEAK_DETECT_THRESHOLD 15
|
||||
|
||||
int16_t saturating_sub(int16_t a, int16_t b)
|
||||
{
|
||||
int32_t result = (int32_t)a - (int32_t)b;
|
||||
@@ -367,20 +369,28 @@ void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates
|
||||
int max_val = delay->delay_max_val;
|
||||
const int sync_pos = 0;
|
||||
|
||||
uint64_t mean_val = 0;
|
||||
for (int i = 0; i < ofdm_symbol_size; i++) {
|
||||
int temp = c16amp2(ch_estimates_time[i]) >> 1;
|
||||
mean_val += temp;
|
||||
if (temp > max_val) {
|
||||
max_pos = i;
|
||||
max_val = temp;
|
||||
}
|
||||
}
|
||||
mean_val /= ofdm_symbol_size;
|
||||
|
||||
if (max_pos > ofdm_symbol_size / 2)
|
||||
max_pos = max_pos - ofdm_symbol_size;
|
||||
|
||||
delay->delay_max_pos = max_pos;
|
||||
delay->delay_max_val = max_val;
|
||||
delay->est_delay = max_pos - sync_pos;
|
||||
|
||||
// The peak in general is quite clear. It only gives a small peak when the noise is high, generally obtaining an incorrect
|
||||
// estimated delay, and causing the delay compensation to worsen the result instead of improving it. After analyzing several
|
||||
// peaks, and doing many tests, a PEAK_DETECT_THRESHOLD = 15 is an adequate value, to apply delay compensation only when there is
|
||||
// clearly a peak
|
||||
delay->est_delay = mean_val > 0 && max_val / mean_val > PEAK_DETECT_THRESHOLD ? max_pos - sync_pos : 0;
|
||||
}
|
||||
|
||||
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb)
|
||||
|
||||
@@ -144,6 +144,7 @@ int main(int argc, char **argv)
|
||||
int sr_flag = 0;
|
||||
int pucch_DTX_thres = 0;
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
bool print_perf = false;
|
||||
|
||||
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == 0) {
|
||||
exit_fun("[NR_PUCCHSIM] Error, configuration module init failed\n");
|
||||
@@ -153,8 +154,7 @@ int main(int argc, char **argv)
|
||||
logInit();
|
||||
|
||||
int c;
|
||||
while ((c = getopt (argc, argv, "--:O:f:hA:f:g:i:I:P:B:b:t:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:cd:")) != -1) {
|
||||
|
||||
while ((c = getopt(argc, argv, "--:O:f:hA:f:g:i:I:P:B:b:t:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:cd:C")) != -1) {
|
||||
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
|
||||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||||
if (c == 1 || c == '-' || c == 'O')
|
||||
@@ -349,6 +349,10 @@ int main(int argc, char **argv)
|
||||
//nacktoack_flag=(uint8_t)atoi(optarg);
|
||||
target_error_rate=0.001;
|
||||
break;
|
||||
case 'C':
|
||||
print_perf = 1;
|
||||
cpu_meas_enabled = 1;
|
||||
break;
|
||||
default:
|
||||
case 'h':
|
||||
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
|
||||
@@ -381,6 +385,7 @@ int main(int argc, char **argv)
|
||||
printf("-x Transmission mode (1,2,6 for the moment)\n");
|
||||
printf("-y Number of TX antennas used in eNB\n");
|
||||
printf("-z Number of RX antennas used in UE\n");
|
||||
printf("-C print CPU cost\n");
|
||||
exit (-1);
|
||||
break;
|
||||
}
|
||||
@@ -406,8 +411,8 @@ int main(int argc, char **argv)
|
||||
if ((format < 2) && (actual_payload == 4)) do_DTX=1;
|
||||
|
||||
if (random_payload) {
|
||||
srand(time(NULL)); // Initialization, should only be called once.
|
||||
actual_payload = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.
|
||||
double tmp = uniformrandom();
|
||||
memcpy(&actual_payload, &tmp, sizeof(actual_payload));
|
||||
}
|
||||
actual_payload &= nr_bit < 64 ? (1UL << nr_bit) - 1: 0xffffffffffffffff;
|
||||
|
||||
@@ -638,6 +643,7 @@ int main(int argc, char **argv)
|
||||
|
||||
// noise measurement (all PRBs)
|
||||
gNB_I0_measurements(gNB, nr_slot_tx, 0, gNB->frame_parms.symbols_per_slot, rb_mask_ul);
|
||||
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(format==0){
|
||||
@@ -731,10 +737,21 @@ int main(int argc, char **argv)
|
||||
free(uci_pdu.csi_part1.csi_part1_payload);
|
||||
|
||||
}
|
||||
stop_meas(&gNB->phy_proc_rx);
|
||||
|
||||
n_errors=((actual_payload^payload_received)&1)+(((actual_payload^payload_received)&2)>>1)+(((actual_payload^payload_received)&4)>>2)+n_errors;
|
||||
}
|
||||
if (sr_flag == 1)
|
||||
printf("SR: SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,sr_errors);
|
||||
if (print_perf) {
|
||||
time_stats_t *ts = &gNB->phy_proc_rx;
|
||||
printf("cpu time for pucch format %d: per block %.2f us; nb blocks %d, max time %.2f;\n",
|
||||
format,
|
||||
ts->diff / ts->trials / cpuf / 1000.0,
|
||||
ts->trials,
|
||||
ts->max / cpuf / 1000.0);
|
||||
reset_meas(ts);
|
||||
}
|
||||
if(nr_bit > 0)
|
||||
printf("ACK/NACK: SNR=%f, n_trials=%d, n_bit_errors=%d\n",SNR,n_trials,ack_nack_errors);
|
||||
if((float)(ack_nack_errors+sr_errors)/(float)(n_trials)<=target_error_rate){
|
||||
|
||||
Reference in New Issue
Block a user