Merge remote-tracking branch 'origin/new' into new
This commit is contained in:
@@ -32,7 +32,7 @@ channelmod = {
|
||||
model_name = "rfsimu_channel_enB0"
|
||||
type = "AWGN";
|
||||
ploss_dB = 20;
|
||||
noise_power_dB = -4;
|
||||
noise_power_dB = -2;
|
||||
forgetfact = 0;
|
||||
offset = 0;
|
||||
ds_tdl = 0;
|
||||
@@ -40,8 +40,8 @@ channelmod = {
|
||||
{ # UL, modify on gNB side
|
||||
model_name = "rfsimu_channel_ue0"
|
||||
type = "AWGN";
|
||||
ploss_dB = 20;
|
||||
noise_power_dB = -2;
|
||||
ploss_dB = 0;
|
||||
noise_power_dB = -100;
|
||||
forgetfact = 0;
|
||||
offset = 0;
|
||||
ds_tdl = 0;
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
#define MAX_NUM_SLICES 1024
|
||||
|
||||
// RLC Entity
|
||||
#define RLC_TX_MAXSIZE 10000000
|
||||
#define RLC_TX_MAXSIZE 50000
|
||||
#define RLC_RX_MAXSIZE 10000000
|
||||
#define SEND_MRW_ON 240
|
||||
#define MAX_ANT 8
|
||||
|
||||
@@ -143,13 +143,15 @@ static void nr_hermitian_eigenvalues(const int N, float A_re[4][4], float A_im[4
|
||||
float cos_phi = re_pq / mag;
|
||||
float sin_phi = im_pq / mag;
|
||||
|
||||
// Multiply column q by e^{-j*phi} and row q by e^{+j*phi}
|
||||
// Similarity transformation D^H A D with D=diag(1,..,e^{-jphi},..,1)
|
||||
// Column q: A[k][q] *= e^{-jphi} for k != q (diagonal unchanged)
|
||||
for (int k = 0; k < N; k++) {
|
||||
if (k == q) continue;
|
||||
float old_re = A_re[k][q], old_im = A_im[k][q];
|
||||
A_re[k][q] = old_re * cos_phi + old_im * sin_phi;
|
||||
A_im[k][q] = -old_re * sin_phi + old_im * cos_phi;
|
||||
}
|
||||
// Row q from Hermitian symmetry: A[q][k] = conj(A[k][q])
|
||||
for (int k = 0; k < N; k++) {
|
||||
if (k == q)
|
||||
continue;
|
||||
@@ -564,6 +566,7 @@ int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
|
||||
c16_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports]
|
||||
[frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
|
||||
int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
|
||||
memset(csi_rs_estimated_A_MF, 0, sizeof(csi_rs_estimated_A_MF));
|
||||
|
||||
// Arrays only needed for the 2x2 fast path
|
||||
int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
|
||||
@@ -689,6 +692,7 @@ int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef NR_CSIRS_DEBUG
|
||||
LOG_I(NR_PHY, "(%i) sc %d eigenvalues: %.1f %.1f %.1f %.1f\n",
|
||||
k, sc_idx, eig[0], eig[1], eig[2], eig[3]);
|
||||
@@ -980,6 +984,151 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue,
|
||||
if (best_sinr > 0)
|
||||
*precoded_sinr_dB = dB_fixed((best_sinr / 2) / interference_plus_noise_power);
|
||||
|
||||
} else if (rank_indicator == 2) {
|
||||
// Rank 3: three-layer precoder using beam pairs (TS 38.214 Table 5.2.2.2.1-5)
|
||||
// W(l,n) = 1/(2*sqrt(3)) * [v_a v_a v_b; phi_n*v_a -phi_n*v_a phi_n*v_b]
|
||||
// where v_a = [1; w1_{2l}], v_b = [1; -w1_{2l}] (orthogonal beam pair)
|
||||
// i1[0] = l in {0,...,N1*O1/2-1} = {0,1,2,3}, i2[0] = n in {0,1}
|
||||
// Layer 0: A + phi*B, Layer 1: A - phi*B, Layer 2: A' + phi*B'
|
||||
// where A = h0 + w1*h1, B = h2 + w1*h3, A' = h0 - w1*h1, B' = h2 - w1*h3
|
||||
int64_t best_sinr = -1;
|
||||
uint8_t best_l = 0, best_n = 0;
|
||||
const int N_beam_pairs = 4; // N1*O1/2
|
||||
|
||||
for (int l = 0; l < N_beam_pairs; l++) {
|
||||
int beam_a = 2 * l; // first beam index in DFT grid
|
||||
int64_t power[2] = {0};
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb + csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2))
|
||||
continue;
|
||||
uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
uint16_t k_offset = k + mem_offset;
|
||||
|
||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||
const c16_t h0 = csi_rs_estimated_channel_freq[ant_rx][0][k_offset];
|
||||
const c16_t h1 = csi_rs_estimated_channel_freq[ant_rx][1][k_offset];
|
||||
const c16_t h2 = csi_rs_estimated_channel_freq[ant_rx][2][k_offset];
|
||||
const c16_t h3 = csi_rs_estimated_channel_freq[ant_rx][3][k_offset];
|
||||
|
||||
float w1r = w1_re[beam_a], w1i = w1_im[beam_a];
|
||||
|
||||
// A = h0 + w1*h1 (beam a, ports 0-1)
|
||||
float A_re = (float)h0.r + w1r * h1.r - w1i * h1.i;
|
||||
float A_im = (float)h0.i + w1r * h1.i + w1i * h1.r;
|
||||
// B = h2 + w1*h3 (beam a, ports 2-3)
|
||||
float B_re = (float)h2.r + w1r * h3.r - w1i * h3.i;
|
||||
float B_im = (float)h2.i + w1r * h3.i + w1i * h3.r;
|
||||
// A' = h0 - w1*h1 (beam b, ports 0-1)
|
||||
float Ap_re = (float)h0.r - w1r * h1.r + w1i * h1.i;
|
||||
float Ap_im = (float)h0.i - w1r * h1.i - w1i * h1.r;
|
||||
// B' = h2 - w1*h3 (beam b, ports 2-3)
|
||||
float Bp_re = (float)h2.r - w1r * h3.r + w1i * h3.i;
|
||||
float Bp_im = (float)h2.i - w1r * h3.i - w1i * h3.r;
|
||||
|
||||
for (int n = 0; n < 2; n++) {
|
||||
// Layer 0: A + phi_n * B
|
||||
float l0_re = A_re + w2_re[n] * B_re - w2_im[n] * B_im;
|
||||
float l0_im = A_im + w2_re[n] * B_im + w2_im[n] * B_re;
|
||||
// Layer 1: A - phi_n * B
|
||||
float l1_re = A_re - w2_re[n] * B_re + w2_im[n] * B_im;
|
||||
float l1_im = A_im - w2_re[n] * B_im - w2_im[n] * B_re;
|
||||
// Layer 2: A' + phi_n * B'
|
||||
float l2_re = Ap_re + w2_re[n] * Bp_re - w2_im[n] * Bp_im;
|
||||
float l2_im = Ap_im + w2_re[n] * Bp_im + w2_im[n] * Bp_re;
|
||||
|
||||
power[n] += (int64_t)(l0_re * l0_re + l0_im * l0_im
|
||||
+ l1_re * l1_re + l1_im * l1_im
|
||||
+ l2_re * l2_re + l2_im * l2_im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < 2; n++) {
|
||||
if (power[n] > best_sinr) {
|
||||
best_sinr = power[n];
|
||||
best_l = l;
|
||||
best_n = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i1[0] = best_l;
|
||||
i1[1] = 0;
|
||||
i1[2] = 0;
|
||||
i2[0] = best_n;
|
||||
if (best_sinr > 0)
|
||||
*precoded_sinr_dB = dB_fixed((best_sinr / 3) / interference_plus_noise_power);
|
||||
|
||||
} else if (rank_indicator == 3) {
|
||||
// Rank 4: four-layer precoder using beam pairs (TS 38.214 Table 5.2.2.2.1-5)
|
||||
// W(l,n) = 1/4 * [v_a v_a v_b v_b; phi_n*v_a -phi_n*v_a phi_n*v_b -phi_n*v_b]
|
||||
// Layer 0: A + phi*B, Layer 1: A - phi*B, Layer 2: A' + phi*B', Layer 3: A' - phi*B'
|
||||
int64_t best_sinr = -1;
|
||||
uint8_t best_l = 0, best_n = 0;
|
||||
const int N_beam_pairs = 4;
|
||||
|
||||
for (int l = 0; l < N_beam_pairs; l++) {
|
||||
int beam_a = 2 * l;
|
||||
int64_t power[2] = {0};
|
||||
|
||||
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb + csirs_config_pdu->nr_of_rbs); rb++) {
|
||||
if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2))
|
||||
continue;
|
||||
uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
|
||||
uint16_t k_offset = k + mem_offset;
|
||||
|
||||
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
|
||||
const c16_t h0 = csi_rs_estimated_channel_freq[ant_rx][0][k_offset];
|
||||
const c16_t h1 = csi_rs_estimated_channel_freq[ant_rx][1][k_offset];
|
||||
const c16_t h2 = csi_rs_estimated_channel_freq[ant_rx][2][k_offset];
|
||||
const c16_t h3 = csi_rs_estimated_channel_freq[ant_rx][3][k_offset];
|
||||
|
||||
float w1r = w1_re[beam_a], w1i = w1_im[beam_a];
|
||||
|
||||
float A_re = (float)h0.r + w1r * h1.r - w1i * h1.i;
|
||||
float A_im = (float)h0.i + w1r * h1.i + w1i * h1.r;
|
||||
float B_re = (float)h2.r + w1r * h3.r - w1i * h3.i;
|
||||
float B_im = (float)h2.i + w1r * h3.i + w1i * h3.r;
|
||||
float Ap_re = (float)h0.r - w1r * h1.r + w1i * h1.i;
|
||||
float Ap_im = (float)h0.i - w1r * h1.i - w1i * h1.r;
|
||||
float Bp_re = (float)h2.r - w1r * h3.r + w1i * h3.i;
|
||||
float Bp_im = (float)h2.i - w1r * h3.i - w1i * h3.r;
|
||||
|
||||
for (int n = 0; n < 2; n++) {
|
||||
float l0_re = A_re + w2_re[n] * B_re - w2_im[n] * B_im;
|
||||
float l0_im = A_im + w2_re[n] * B_im + w2_im[n] * B_re;
|
||||
float l1_re = A_re - w2_re[n] * B_re + w2_im[n] * B_im;
|
||||
float l1_im = A_im - w2_re[n] * B_im - w2_im[n] * B_re;
|
||||
float l2_re = Ap_re + w2_re[n] * Bp_re - w2_im[n] * Bp_im;
|
||||
float l2_im = Ap_im + w2_re[n] * Bp_im + w2_im[n] * Bp_re;
|
||||
float l3_re = Ap_re - w2_re[n] * Bp_re + w2_im[n] * Bp_im;
|
||||
float l3_im = Ap_im - w2_re[n] * Bp_im - w2_im[n] * Bp_re;
|
||||
|
||||
power[n] += (int64_t)(l0_re * l0_re + l0_im * l0_im
|
||||
+ l1_re * l1_re + l1_im * l1_im
|
||||
+ l2_re * l2_re + l2_im * l2_im
|
||||
+ l3_re * l3_re + l3_im * l3_im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int n = 0; n < 2; n++) {
|
||||
if (power[n] > best_sinr) {
|
||||
best_sinr = power[n];
|
||||
best_l = l;
|
||||
best_n = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i1[0] = best_l;
|
||||
i1[1] = 0;
|
||||
i1[2] = 0;
|
||||
i2[0] = best_n;
|
||||
if (best_sinr > 0)
|
||||
*precoded_sinr_dB = dB_fixed((best_sinr / 4) / interference_plus_noise_power);
|
||||
|
||||
} else {
|
||||
// RI=3 or RI=4: Use identity-like precoder (i1=0, i2=0)
|
||||
// Compute SINR from per-layer effective channel power with identity precoding
|
||||
|
||||
@@ -10,14 +10,16 @@ set -euo pipefail
|
||||
PROFILE="${PROFILE:-}"
|
||||
|
||||
# Fixed server coordinates
|
||||
IPERF_HOST_UDP="192.168.71.129"
|
||||
IPERF_HOST_UDP="192.168.71.130"
|
||||
IPERF_HOST_TCP="192.168.71.130"
|
||||
IPERF_PORT_UDP=5201
|
||||
IPERF_PORT_TCP=5202
|
||||
OAITUN_IP="$(ip -o -4 addr show dev oaitun_ue1 | awk '{print $4}' | cut -d/ -f1)"
|
||||
|
||||
# Per-UE port: derive from last octet of oaitun IP (12.1.1.x → port 5200+x)
|
||||
UE_OCTET="${OAITUN_IP##*.}"
|
||||
IPERF_PORT=$((5200 + UE_OCTET))
|
||||
|
||||
# Very long duration to approximate "forever"
|
||||
LONG_T="${LONG_T:-31536000}" # 1 year in seconds
|
||||
LONG_T="${LONG_T:-86400}" # 24h (iperf3 max)
|
||||
|
||||
# -------------- args --------------
|
||||
if [[ $# -gt 0 ]]; then
|
||||
@@ -33,15 +35,17 @@ fi
|
||||
|
||||
[[ -n "$PROFILE" ]] || { echo "ERROR: --profile is required" >&2; exit 2; }
|
||||
|
||||
iperf_tcp_dl_forever() { ( iperf -c "$IPERF_HOST_TCP" -B "$OAITUN_IP" -p "$IPERF_PORT_TCP" -R -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_tcp_ul_forever() { ( iperf -c "$IPERF_HOST_TCP" -B "$OAITUN_IP" -p "$IPERF_PORT_TCP" -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
# iperf_udp_dl_forever() { ( nohup iperf -u -c "$IPERF_HOST_UDP" -B "$OAITUN_IP" -p "$IPERF_PORT_UDP" -R -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_udp_dl_forever() { ( iperf -u -c "$IPERF_HOST_UDP" -B "$OAITUN_IP" -p "$IPERF_PORT_UDP" -R -b $1 -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_udp_ul_forever() { ( iperf -u -c "$IPERF_HOST_UDP" -B "$OAITUN_IP" -p "$IPERF_PORT_UDP" -b $1 -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_tcp_dl_forever() { ( iperf -c "$IPERF_HOST_TCP" -B "$OAITUN_IP" -p "$IPERF_PORT" -R -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_tcp_ul_forever() { ( iperf -c "$IPERF_HOST_TCP" -B "$OAITUN_IP" -p "$IPERF_PORT" -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
# Use iperf3 for UDP DL — iperf2 -R does not properly pass -b bandwidth to server
|
||||
iperf_udp_dl_forever() { ( iperf3 -u -c "$IPERF_HOST_UDP" -B "$OAITUN_IP" -p "$IPERF_PORT" -R -b $1 -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_udp_ul_forever() { ( iperf3 -u -c "$IPERF_HOST_UDP" -B "$OAITUN_IP" -p "$IPERF_PORT" -b $1 -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
iperf_tcp_dl_parallel_forever() { ( iperf -c "$IPERF_HOST_TCP" -B "$OAITUN_IP" -p "$IPERF_PORT" -R -w 10M -P 8 -t "$LONG_T" >/dev/null 2>&1 ); }
|
||||
|
||||
# ---------------- profiles ----------------
|
||||
do_boring() {
|
||||
iperf_udp_dl_forever 1M
|
||||
# iperf_tcp_dl_parallel_forever
|
||||
iperf_udp_dl_forever 8M
|
||||
wait
|
||||
# iperf -c "$IPERF_HOST" -p "$IPERF_PORT" -B "$OAITUN_IP" -u -b 25M -t "$LONG_T"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user