Merge remote-tracking branch 'origin/new' into new

This commit is contained in:
2026-02-15 22:15:49 +09:00
4 changed files with 168 additions and 15 deletions
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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
+150 -1
View File
@@ -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
+14 -10
View File
@@ -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"
}